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

Side by Side Diff: src/objects.cc

Issue 155350: Changed hash table to use more of the hash value when probing. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 5 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
OLDNEW
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 6484 matching lines...) Expand 10 before | Expand all | Expand 10 after
6495 IteratePointers(v, 6495 IteratePointers(v,
6496 kElementsStartOffset, 6496 kElementsStartOffset,
6497 kHeaderSize + length() * kPointerSize); 6497 kHeaderSize + length() * kPointerSize);
6498 } 6498 }
6499 6499
6500 6500
6501 template<typename Shape, typename Key> 6501 template<typename Shape, typename Key>
6502 Object* HashTable<Shape, Key>::Allocate( 6502 Object* HashTable<Shape, Key>::Allocate(
6503 int at_least_space_for) { 6503 int at_least_space_for) {
6504 int capacity = RoundUpToPowerOf2(at_least_space_for); 6504 int capacity = RoundUpToPowerOf2(at_least_space_for);
6505 if (capacity < 4) capacity = 4; // Guarantee min capacity. 6505 static const int kMinCapacity = 16;
6506 if (capacity < kMinCapacity) capacity = kMinCapacity;
6506 Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity)); 6507 Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity));
6507 if (!obj->IsFailure()) { 6508 if (!obj->IsFailure()) {
6508 HashTable::cast(obj)->SetNumberOfElements(0); 6509 HashTable::cast(obj)->SetNumberOfElements(0);
6509 HashTable::cast(obj)->SetCapacity(capacity); 6510 HashTable::cast(obj)->SetCapacity(capacity);
6510 } 6511 }
6511 return obj; 6512 return obj;
6512 } 6513 }
6513 6514
6514 6515
6515 6516
6516 // Find entry for key otherwise return -1. 6517 // Find entry for key otherwise return -1.
6517 template<typename Shape, typename Key> 6518 template<typename Shape, typename Key>
6518 int HashTable<Shape, Key>::FindEntry(Key key) { 6519 int HashTable<Shape, Key>::FindEntry(Key key) {
6519 uint32_t nof = NumberOfElements(); 6520 uint32_t mask = Capacity() - 1;
6520 if (nof == 0) return kNotFound; // Bail out if empty. 6521 uint32_t hash = Shape::Hash(key);
6521 6522
6522 uint32_t capacity = Capacity(); 6523 // For the first probes rotate the hash to ensure a proper spread.
6523 uint32_t hash = Shape::Hash(key); 6524 for (uint32_t i = 0; i < kNofFastProbes; i++) {
6524 uint32_t entry = GetProbe(hash, 0, capacity); 6525 int entry = hash & mask;
6526 Object* element = KeyAt(entry);
6527 if (element->IsUndefined()) return kNotFound;
6528 if (!element->IsNull() && Shape::IsMatch(key, element)) return entry;
6529 hash = RotateRight(hash, kHashRotateShift);
6530 }
6525 6531
6526 Object* element = KeyAt(entry); 6532
6527 uint32_t passed_elements = 0; 6533 // In this unlikely event, do a linear scan.
6528 if (!element->IsNull()) { 6534 for (uint32_t i = 1; i <= mask; i++) {
6529 if (!element->IsUndefined() && Shape::IsMatch(key, element)) return entry; 6535 int entry = ++hash & mask;
6530 if (++passed_elements == nof) return kNotFound; 6536 Object* element = KeyAt(entry);
6531 } 6537 if (element->IsUndefined()) return kNotFound;
6532 for (uint32_t i = 1; !element->IsUndefined(); i++) { 6538 if (!element->IsNull() && Shape::IsMatch(key, element)) return entry;
6533 entry = GetProbe(hash, i, capacity);
6534 element = KeyAt(entry);
6535 if (!element->IsNull()) {
6536 if (!element->IsUndefined() && Shape::IsMatch(key, element)) return entry;
6537 if (++passed_elements == nof) return kNotFound;
6538 }
6539 } 6539 }
6540 return kNotFound; 6540 return kNotFound;
6541 } 6541 }
6542 6542
6543 6543
6544 template<typename Shape, typename Key> 6544 template<typename Shape, typename Key>
6545 Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { 6545 Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
6546 int capacity = Capacity(); 6546 int capacity = Capacity();
6547 int nof = NumberOfElements() + n; 6547 int nof = NumberOfElements() + n;
6548 // Make sure 50% is free 6548 // Make sure 50% is free
6549 if (nof + (nof >> 1) <= capacity) return this; 6549 if (nof + (nof>>1) <= capacity) return this;
Kasper Lund 2009/07/16 12:41:43 Why did you remove the whitespace here?
bak 2009/07/16 12:52:41 Too old to remember. I've added the missing spaces
6550 6550
6551 Object* obj = Allocate(nof * 2); 6551 Object* obj = Allocate(nof * 2);
6552 if (obj->IsFailure()) return obj; 6552 if (obj->IsFailure()) return obj;
6553 HashTable* table = HashTable::cast(obj); 6553 HashTable* table = HashTable::cast(obj);
6554 WriteBarrierMode mode = table->GetWriteBarrierMode(); 6554 WriteBarrierMode mode = table->GetWriteBarrierMode();
6555 6555
6556 // Copy prefix to new array. 6556 // Copy prefix to new array.
6557 for (int i = kPrefixStartIndex; 6557 for (int i = kPrefixStartIndex;
6558 i < kPrefixStartIndex + Shape::kPrefixSize; 6558 i < kPrefixStartIndex + Shape::kPrefixSize;
6559 i++) { 6559 i++) {
(...skipping 12 matching lines...) Expand all
6572 } 6572 }
6573 } 6573 }
6574 } 6574 }
6575 table->SetNumberOfElements(NumberOfElements()); 6575 table->SetNumberOfElements(NumberOfElements());
6576 return table; 6576 return table;
6577 } 6577 }
6578 6578
6579 6579
6580 template<typename Shape, typename Key> 6580 template<typename Shape, typename Key>
6581 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { 6581 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) {
6582 uint32_t capacity = Capacity(); 6582 uint32_t mask = Capacity() - 1;
6583 uint32_t entry = GetProbe(hash, 0, capacity); 6583 int entry;
6584 Object* element = KeyAt(entry); 6584 Object* element;
6585 6585
6586 for (uint32_t i = 1; !(element->IsUndefined() || element->IsNull()); i++) { 6586 // For the first probes rotate the hash to ensure a proper spread.
6587 entry = GetProbe(hash, i, capacity); 6587 for (uint32_t i = 0; i < kNofFastProbes; i++) {
6588 entry = hash & mask;
6588 element = KeyAt(entry); 6589 element = KeyAt(entry);
6590 if (element->IsUndefined() || element->IsNull()) return entry;
6591 hash = RotateRight(hash, kHashRotateShift);
6589 } 6592 }
6590 6593
6594 do {
6595 entry = ++hash & mask;
6596 element = KeyAt(entry);
6597 } while(!(element->IsUndefined() || element->IsNull()));
6598
6591 return entry; 6599 return entry;
6592 } 6600 }
6593 6601
6594 // Force instantiation of template instances class. 6602 // Force instantiation of template instances class.
6595 // Please note this list is compiler dependent. 6603 // Please note this list is compiler dependent.
6596 6604
6597 template class HashTable<SymbolTableShape, HashTableKey*>; 6605 template class HashTable<SymbolTableShape, HashTableKey*>;
6598 6606
6599 template class HashTable<CompilationCacheShape, HashTableKey*>; 6607 template class HashTable<CompilationCacheShape, HashTableKey*>;
6600 6608
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
6659 6667
6660 template Object* Dictionary<StringDictionaryShape, String*>::AddEntry( 6668 template Object* Dictionary<StringDictionaryShape, String*>::AddEntry(
6661 String*, Object*, PropertyDetails, uint32_t); 6669 String*, Object*, PropertyDetails, uint32_t);
6662 6670
6663 template 6671 template
6664 int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements(); 6672 int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements();
6665 6673
6666 template 6674 template
6667 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); 6675 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements();
6668 6676
6677 template
6678 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t key);
6679
6680
6669 // Collates undefined and unexisting elements below limit from position 6681 // Collates undefined and unexisting elements below limit from position
6670 // zero of the elements. The object stays in Dictionary mode. 6682 // zero of the elements. The object stays in Dictionary mode.
6671 Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) { 6683 Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
6672 ASSERT(!HasFastElements()); 6684 ASSERT(!HasFastElements());
6673 // Must stay in dictionary mode, either because of requires_slow_elements, 6685 // Must stay in dictionary mode, either because of requires_slow_elements,
6674 // or because we are not going to sort (and therefore compact) all of the 6686 // or because we are not going to sort (and therefore compact) all of the
6675 // elements. 6687 // elements.
6676 NumberDictionary* dict = element_dictionary(); 6688 NumberDictionary* dict = element_dictionary();
6677 HeapNumber* result_double = NULL; 6689 HeapNumber* result_double = NULL;
6678 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 6690 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
7014 if (o->get(i) != symbols_->get(i)) return false; 7026 if (o->get(i) != symbols_->get(i)) return false;
7015 } 7027 }
7016 return true; 7028 return true;
7017 } 7029 }
7018 7030
7019 uint32_t Hash() { return HashForObject(symbols_); } 7031 uint32_t Hash() { return HashForObject(symbols_); }
7020 7032
7021 uint32_t HashForObject(Object* obj) { 7033 uint32_t HashForObject(Object* obj) {
7022 FixedArray* symbols = FixedArray::cast(obj); 7034 FixedArray* symbols = FixedArray::cast(obj);
7023 int len = symbols->length(); 7035 int len = symbols->length();
7024 uint32_t hash = 0; 7036 uint32_t hash = 40617523; // In case the array is empty.
7025 for (int i = 0; i < len; i++) { 7037 for (int i = 0; i < len; i++) {
7026 hash ^= String::cast(symbols->get(i))->Hash(); 7038 hash ^= String::cast(symbols->get(i))->Hash();
7027 } 7039 }
7028 return hash; 7040 return hash;
7029 } 7041 }
7030 7042
7031 Object* AsObject() { return symbols_; } 7043 Object* AsObject() { return symbols_; }
7032 7044
7033 private: 7045 private:
7034 FixedArray* symbols_; 7046 FixedArray* symbols_;
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
7747 if (break_point_objects()->IsUndefined()) return 0; 7759 if (break_point_objects()->IsUndefined()) return 0;
7748 // Single beak point. 7760 // Single beak point.
7749 if (!break_point_objects()->IsFixedArray()) return 1; 7761 if (!break_point_objects()->IsFixedArray()) return 1;
7750 // Multiple break points. 7762 // Multiple break points.
7751 return FixedArray::cast(break_point_objects())->length(); 7763 return FixedArray::cast(break_point_objects())->length();
7752 } 7764 }
7753 #endif 7765 #endif
7754 7766
7755 7767
7756 } } // namespace v8::internal 7768 } } // namespace v8::internal
OLDNEW
« src/arm/ic-arm.cc ('K') | « src/objects.h ('k') | src/utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698