Chromium Code Reviews| 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 |