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

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: Actually use pretenure flag 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') | src/objects.cc » ('J')
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
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 static OrderedHashTable* cast(Object* obj) {
Michael Starzinger 2014/04/04 09:38:13 nit: Since this can be considered an abstract clas
adamk 2014/04/04 20:18:35 Removed, this was previously used but no longer.
4295 ASSERT(obj->IsFixedArray()); // TODO(adamk): Make a map for this
4296 return reinterpret_cast<OrderedHashTable*>(obj);
4297 }
4298
4299 // Returns kNotFound if the key isn't present.
4300 int FindEntry(Object* key);
4301
4302 int NumberOfElements() {
4303 return Smi::cast(get(kNumberOfElementsIndex))->value();
4304 }
4305
4306 int NumberOfDeletedElements() {
4307 return Smi::cast(get(kNumberOfDeletedElementsIndex))->value();
4308 }
4309
4310 int NumberOfBuckets() {
4311 return Smi::cast(get(kNumberOfBucketsIndex))->value();
4312 }
4313
4314 // Returns the index into the data table where the new entry
4315 // should be placed. The table is assumed to have enough space
4316 // for a new entry.
4317 int AddEntry(int hash);
4318
4319 // Removes the entry, and puts the_hole in entrysize pointers
4320 // (leaving the hash table chain intact).
4321 void RemoveEntry(int entry);
4322
4323 // Returns an index into |this| for the given entry.
4324 int EntryToIndex(int entry) {
4325 return kHashTableStartIndex + NumberOfBuckets() + (entry * kEntrySize);
4326 }
4327
4328 static const int kNotFound = -1;
4329
4330 private:
4331 static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
4332
4333 void SetNumberOfBuckets(int num) {
4334 set(kNumberOfBucketsIndex, Smi::FromInt(num));
4335 }
4336
4337 void SetNumberOfElements(int num) {
4338 set(kNumberOfElementsIndex, Smi::FromInt(num));
4339 }
4340
4341 void SetNumberOfDeletedElements(int num) {
4342 set(kNumberOfDeletedElementsIndex, Smi::FromInt(num));
4343 }
4344
4345 int Capacity() {
4346 return NumberOfBuckets() * kLoadFactor;
4347 }
4348
4349 Object* KeyAt(int entry) { return get(EntryToIndex(entry)); }
4350
4351 // Returns the next entry for the given entry.
4352 int ChainAt(int entry) {
4353 return Smi::cast(get(EntryToIndex(entry) + kChainOffset))->value();
4354 }
4355
4356 int HashToBucket(int hash) {
4357 return hash & (NumberOfBuckets() - 1);
4358 }
4359
4360 int HashToEntry(int hash) {
4361 int bucket = HashToBucket(hash);
4362 return Smi::cast(get(kHashTableStartIndex + bucket))->value();
4363 }
4364
4365 static const int kNumberOfBucketsIndex = 0;
4366 static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
4367 static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
4368 static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
4369
4370 static const int kEntrySize = entrysize + 1;
4371 static const int kChainOffset = entrysize;
4372
4373 static const int kLoadFactor = 2;
4374 static const int kMaxCapacity =
4375 (FixedArray::kMaxLength - kHashTableStartIndex)
4376 / (1 + (kEntrySize * kLoadFactor));
4377 };
4378
4379
4380 class OrderedHashSet: public OrderedHashTable<OrderedHashSet, 1> {
4381 public:
4382 static OrderedHashSet* cast(Object* obj) {
4383 ASSERT(obj->IsFixedArray()); // TODO(adamk): Make a map for this
4384 return reinterpret_cast<OrderedHashSet*>(obj);
4385 }
4386
4387 bool Contains(Object* key);
4388 static Handle<OrderedHashSet> Add(
4389 Handle<OrderedHashSet> table, Handle<Object> key);
4390 static Handle<OrderedHashSet> Remove(
4391 Handle<OrderedHashSet> table, Handle<Object> key);
4392 };
4393
4394
4395 class OrderedHashMap: public OrderedHashTable<OrderedHashMap, 2> {
4396 public:
4397 static OrderedHashMap* cast(Object* obj) {
4398 ASSERT(obj->IsFixedArray()); // TODO(adamk): Make a map for this
4399 return reinterpret_cast<OrderedHashMap*>(obj);
4400 }
4401
4402 Object* Lookup(Object* key);
4403 static Handle<OrderedHashMap> Put(
4404 Handle<OrderedHashMap> table,
4405 Handle<Object> key,
4406 Handle<Object> value);
4407
4408 private:
4409 Object* ValueAt(int entry) {
4410 return get(EntryToIndex(entry) + kValueOffset);
4411 }
4412
4413 static const int kValueOffset = 1;
4414 };
4415
4416
4252 template <int entrysize> 4417 template <int entrysize>
4253 class WeakHashTableShape : public BaseShape<Object*> { 4418 class WeakHashTableShape : public BaseShape<Object*> {
4254 public: 4419 public:
4255 static inline bool IsMatch(Object* key, Object* other); 4420 static inline bool IsMatch(Object* key, Object* other);
4256 static inline uint32_t Hash(Object* key); 4421 static inline uint32_t Hash(Object* key);
4257 static inline uint32_t HashForObject(Object* key, Object* object); 4422 static inline uint32_t HashForObject(Object* key, Object* object);
4258 MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap, 4423 MUST_USE_RESULT static inline MaybeObject* AsObject(Heap* heap,
4259 Object* key); 4424 Object* key);
4260 static const int kPrefixSize = 0; 4425 static const int kPrefixSize = 0;
4261 static const int kEntrySize = entrysize; 4426 static const int kEntrySize = entrysize;
(...skipping 6524 matching lines...) Expand 10 before | Expand all | Expand 10 after
10786 } else { 10951 } else {
10787 value &= ~(1 << bit_position); 10952 value &= ~(1 << bit_position);
10788 } 10953 }
10789 return value; 10954 return value;
10790 } 10955 }
10791 }; 10956 };
10792 10957
10793 } } // namespace v8::internal 10958 } } // namespace v8::internal
10794 10959
10795 #endif // V8_OBJECTS_H_ 10960 #endif // V8_OBJECTS_H_
OLDNEW
« no previous file with comments | « src/factory.cc ('k') | src/objects.cc » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698