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 6484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |