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

Unified Diff: runtime/vm/hash_map.h

Issue 11273111: Allow bound check elimination to eliminate checks when both array length and index boundaries are e… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Florian's comments Created 8 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/hash_map_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/hash_map.h
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 0c41f1221c8873d3f5d8269a113f53e769587e92..22efc32ba391194cb447380a797d310900acde9d 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -7,7 +7,7 @@
namespace dart {
-template <typename T>
+template <typename KeyValueTrait>
class DirectChainedHashMap: public ValueObject {
public:
DirectChainedHashMap() : array_size_(0),
@@ -22,16 +22,16 @@ class DirectChainedHashMap: public ValueObject {
DirectChainedHashMap(const DirectChainedHashMap& other);
- void Insert(T value);
+ void Insert(typename KeyValueTrait::Pair kv);
- T Lookup(T value) const;
+ typename KeyValueTrait::Value Lookup(typename KeyValueTrait::Key key) const;
bool IsEmpty() const { return count_ == 0; }
private:
// A linked list of T values. Stored in arrays.
struct HashMapListElement {
- T value;
+ typename KeyValueTrait::Pair kv;
intptr_t next; // Index in the array of the next list element.
};
static const intptr_t kNil = -1; // The end of a linked list
@@ -53,15 +53,22 @@ class DirectChainedHashMap: public ValueObject {
};
-template <typename T>
-T DirectChainedHashMap<T>::Lookup(T value) const {
- uword hash = static_cast<uword>(value->Hashcode());
+template <typename KeyValueTrait>
+typename KeyValueTrait::Value
+ DirectChainedHashMap<KeyValueTrait>::
+ Lookup(typename KeyValueTrait::Key key) const {
+ uword hash = static_cast<uword>(KeyValueTrait::Hashcode(key));
uword pos = Bound(hash);
- if (array_[pos].value != NULL) {
- if (array_[pos].value->Equals(value)) return array_[pos].value;
+ if (KeyValueTrait::ValueOf(array_[pos].kv) != NULL) {
+ if (KeyValueTrait::IsKeyEqual(array_[pos].kv, key)) {
+ return KeyValueTrait::ValueOf(array_[pos].kv);
+ }
+
intptr_t next = array_[pos].next;
while (next != kNil) {
- if (lists_[next].value->Equals(value)) return lists_[next].value;
+ if (KeyValueTrait::IsKeyEqual(lists_[next].kv, key)) {
+ return KeyValueTrait::ValueOf(lists_[next].kv);
+ }
next = lists_[next].next;
}
}
@@ -69,8 +76,9 @@ T DirectChainedHashMap<T>::Lookup(T value) const {
}
-template <typename T>
-DirectChainedHashMap<T>::DirectChainedHashMap(const DirectChainedHashMap& other)
+template <typename KeyValueTrait>
+DirectChainedHashMap<KeyValueTrait>::
+ DirectChainedHashMap(const DirectChainedHashMap& other)
: ValueObject(),
array_size_(other.array_size_),
lists_size_(other.lists_size_),
@@ -85,8 +93,8 @@ DirectChainedHashMap<T>::DirectChainedHashMap(const DirectChainedHashMap& other)
}
-template <typename T>
-void DirectChainedHashMap<T>::Resize(intptr_t new_size) {
+template <typename KeyValueTrait>
+void DirectChainedHashMap<KeyValueTrait>::Resize(intptr_t new_size) {
ASSERT(new_size > count_);
// Hashing the values into the new array has no more collisions than in the
// old hash map, so we can use the existing lists_ array, if we are careful.
@@ -111,17 +119,17 @@ void DirectChainedHashMap<T>::Resize(intptr_t new_size) {
if (old_array != NULL) {
// Iterate over all the elements in lists, rehashing them.
for (intptr_t i = 0; i < old_size; ++i) {
- if (old_array[i].value != NULL) {
+ if (KeyValueTrait::ValueOf(old_array[i].kv) != NULL) {
intptr_t current = old_array[i].next;
while (current != kNil) {
- Insert(lists_[current].value);
+ Insert(lists_[current].kv);
intptr_t next = lists_[current].next;
lists_[current].next = free_list_head_;
free_list_head_ = current;
current = next;
}
// Rehash the directly stored value.
- Insert(old_array[i].value);
+ Insert(old_array[i].kv);
}
}
}
@@ -155,16 +163,18 @@ void DirectChainedHashMap<T>::ResizeLists(intptr_t new_size) {
}
-template <typename T>
-void DirectChainedHashMap<T>::Insert(T value) {
- ASSERT(value != NULL);
+template <typename KeyValueTrait>
+void DirectChainedHashMap<KeyValueTrait>::
+ Insert(typename KeyValueTrait::Pair kv) {
+ ASSERT(KeyValueTrait::ValueOf(kv) != NULL);
// Resizing when half of the hashtable is filled up.
if (count_ >= array_size_ >> 1) Resize(array_size_ << 1);
ASSERT(count_ < array_size_);
count_++;
- uword pos = Bound(static_cast<uword>(value->Hashcode()));
- if (array_[pos].value == NULL) {
- array_[pos].value = value;
+ uword pos = Bound(
+ static_cast<uword>(KeyValueTrait::Hashcode(KeyValueTrait::KeyOf(kv))));
+ if (KeyValueTrait::ValueOf(array_[pos].kv) == NULL) {
+ array_[pos].kv = kv;
array_[pos].next = kNil;
} else {
if (free_list_head_ == kNil) {
@@ -173,13 +183,39 @@ void DirectChainedHashMap<T>::Insert(T value) {
intptr_t new_element_pos = free_list_head_;
ASSERT(new_element_pos != kNil);
free_list_head_ = lists_[free_list_head_].next;
- lists_[new_element_pos].value = value;
+ lists_[new_element_pos].kv = kv;
lists_[new_element_pos].next = array_[pos].next;
- ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].value != NULL);
+ ASSERT(array_[pos].next == kNil ||
+ KeyValueTrait::ValueOf(lists_[array_[pos].next].kv) != NULL);
array_[pos].next = new_element_pos;
}
}
+
+template<typename T>
+class PointerKeyValueTrait {
+ public:
+ typedef T* Value;
+ typedef T* Key;
+ typedef T* Pair;
+
+ static Key KeyOf(Pair kv) {
+ return kv;
+ }
+
+ static Value ValueOf(Pair kv) {
+ return kv;
+ }
+
+ static inline intptr_t Hashcode(Key key) {
+ return key->Hashcode();
+ }
+
+ static inline bool IsKeyEqual(Pair kv, Key key) {
+ return kv->Equals(key);
+ }
+};
+
} // namespace dart
#endif // VM_HASH_MAP_H_
« no previous file with comments | « runtime/vm/flow_graph_optimizer.cc ('k') | runtime/vm/hash_map_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698