OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_VM_WEAK_TABLE_H_ | 5 #ifndef RUNTIME_VM_WEAK_TABLE_H_ |
6 #define RUNTIME_VM_WEAK_TABLE_H_ | 6 #define RUNTIME_VM_WEAK_TABLE_H_ |
7 | 7 |
8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
9 | 9 |
10 #include "platform/assert.h" | 10 #include "platform/assert.h" |
11 #include "vm/raw_object.h" | 11 #include "vm/raw_object.h" |
12 | 12 |
13 namespace dart { | 13 namespace dart { |
14 | 14 |
15 class WeakTable { | 15 class WeakTable { |
16 public: | 16 public: |
17 WeakTable() : size_(kMinSize), used_(0), count_(0) { | 17 WeakTable() : size_(kMinSize), used_(0), count_(0) { |
18 ASSERT(Utils::IsPowerOfTwo(size_)); | 18 ASSERT(Utils::IsPowerOfTwo(size_)); |
19 data_ = reinterpret_cast<intptr_t*>(calloc(size_, kEntrySize * kWordSize)); | 19 data_ = reinterpret_cast<intptr_t*>(calloc(size_, kEntrySize * kWordSize)); |
20 } | 20 } |
21 explicit WeakTable(intptr_t size) : used_(0), count_(0) { | 21 explicit WeakTable(intptr_t size) : used_(0), count_(0) { |
22 ASSERT(size >= 0); | 22 ASSERT(size >= 0); |
23 ASSERT(Utils::IsPowerOfTwo(kMinSize)); | 23 ASSERT(Utils::IsPowerOfTwo(kMinSize)); |
24 if (size < kMinSize) { | 24 if (size < kMinSize) { |
25 size = kMinSize; | 25 size = kMinSize; |
26 } | 26 } |
27 // Get a max size that avoids overflows. | 27 // Get a max size that avoids overflows. |
28 const intptr_t kMaxSize = | 28 const intptr_t kMaxSize = |
29 (kIntptrOne << (kBitsPerWord - 2)) / (kEntrySize * kWordSize); | 29 (kIntptrOne << (kBitsPerWord - 2)) / (kEntrySize * kWordSize); |
30 ASSERT(Utils::IsPowerOfTwo(kMaxSize)); | 30 ASSERT(Utils::IsPowerOfTwo(kMaxSize)); |
31 if (size > kMaxSize) { | 31 if (size > kMaxSize) { |
32 size = kMaxSize; | 32 size = kMaxSize; |
33 } | 33 } |
34 size_ = size; | 34 size_ = size; |
35 ASSERT(Utils::IsPowerOfTwo(size_)); | 35 ASSERT(Utils::IsPowerOfTwo(size_)); |
36 data_ = reinterpret_cast<intptr_t*>(calloc(size_, kEntrySize * kWordSize)); | 36 data_ = reinterpret_cast<intptr_t*>(calloc(size_, kEntrySize * kWordSize)); |
37 } | 37 } |
38 | 38 |
39 ~WeakTable() { | 39 ~WeakTable() { free(data_); } |
40 free(data_); | |
41 } | |
42 | 40 |
43 static WeakTable* NewFrom(WeakTable* original) { | 41 static WeakTable* NewFrom(WeakTable* original) { |
44 return new WeakTable(SizeFor(original->count(), original->size())); | 42 return new WeakTable(SizeFor(original->count(), original->size())); |
45 } | 43 } |
46 | 44 |
47 intptr_t size() const { return size_; } | 45 intptr_t size() const { return size_; } |
48 intptr_t used() const { return used_; } | 46 intptr_t used() const { return used_; } |
49 intptr_t count() const { return count_; } | 47 intptr_t count() const { return count_; } |
50 | 48 |
51 bool IsValidEntryAt(intptr_t i) const { | 49 bool IsValidEntryAt(intptr_t i) const { |
52 ASSERT(((ValueAt(i) == 0) && | 50 ASSERT(((ValueAt(i) == 0) && ((ObjectAt(i) == NULL) || |
53 ((ObjectAt(i) == NULL) || | 51 (data_[ObjectIndex(i)] == kDeletedEntry))) || |
54 (data_[ObjectIndex(i)] == kDeletedEntry))) || | 52 ((ValueAt(i) != 0) && (ObjectAt(i) != NULL) && |
55 ((ValueAt(i) != 0) && | |
56 (ObjectAt(i) != NULL) && | |
57 (data_[ObjectIndex(i)] != kDeletedEntry))); | 53 (data_[ObjectIndex(i)] != kDeletedEntry))); |
58 return (data_[ValueIndex(i)] != 0); | 54 return (data_[ValueIndex(i)] != 0); |
59 } | 55 } |
60 | 56 |
61 void InvalidateAt(intptr_t i) { | 57 void InvalidateAt(intptr_t i) { |
62 ASSERT(IsValidEntryAt(i)); | 58 ASSERT(IsValidEntryAt(i)); |
63 SetValueAt(i, 0); | 59 SetValueAt(i, 0); |
64 } | 60 } |
65 | 61 |
66 RawObject* ObjectAt(intptr_t i) const { | 62 RawObject* ObjectAt(intptr_t i) const { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 static const intptr_t kDeletedEntry = 1; // Equivalent to a tagged NULL. | 100 static const intptr_t kDeletedEntry = 1; // Equivalent to a tagged NULL. |
105 static const intptr_t kMinSize = 8; | 101 static const intptr_t kMinSize = 8; |
106 | 102 |
107 static intptr_t SizeFor(intptr_t count, intptr_t size); | 103 static intptr_t SizeFor(intptr_t count, intptr_t size); |
108 static intptr_t LimitFor(intptr_t size) { | 104 static intptr_t LimitFor(intptr_t size) { |
109 // Maintain a maximum of 75% fill rate. | 105 // Maintain a maximum of 75% fill rate. |
110 return 3 * (size / 4); | 106 return 3 * (size / 4); |
111 } | 107 } |
112 intptr_t limit() const { return LimitFor(size()); } | 108 intptr_t limit() const { return LimitFor(size()); } |
113 | 109 |
114 intptr_t index(intptr_t i) const { | 110 intptr_t index(intptr_t i) const { return i * kEntrySize; } |
115 return i * kEntrySize; | |
116 } | |
117 | 111 |
118 void set_used(intptr_t val) { | 112 void set_used(intptr_t val) { |
119 ASSERT(val <= limit()); | 113 ASSERT(val <= limit()); |
120 used_ = val; | 114 used_ = val; |
121 } | 115 } |
122 | 116 |
123 void set_count(intptr_t val) { | 117 void set_count(intptr_t val) { |
124 ASSERT(val <= limit()); | 118 ASSERT(val <= limit()); |
125 ASSERT(val <= used()); | 119 ASSERT(val <= used()); |
126 count_ = val; | 120 count_ = val; |
127 } | 121 } |
128 | 122 |
129 intptr_t ObjectIndex(intptr_t i) const { | 123 intptr_t ObjectIndex(intptr_t i) const { return index(i) + kObjectOffset; } |
130 return index(i) + kObjectOffset; | |
131 } | |
132 | 124 |
133 intptr_t ValueIndex(intptr_t i) const { | 125 intptr_t ValueIndex(intptr_t i) const { return index(i) + kValueOffset; } |
134 return index(i) + kValueOffset; | |
135 } | |
136 | 126 |
137 void SetObjectAt(intptr_t i, RawObject* key) { | 127 void SetObjectAt(intptr_t i, RawObject* key) { |
138 ASSERT(i >= 0); | 128 ASSERT(i >= 0); |
139 ASSERT(i < size()); | 129 ASSERT(i < size()); |
140 data_[ObjectIndex(i)] = reinterpret_cast<intptr_t>(key); | 130 data_[ObjectIndex(i)] = reinterpret_cast<intptr_t>(key); |
141 } | 131 } |
142 | 132 |
143 void SetValueAt(intptr_t i, intptr_t val) { | 133 void SetValueAt(intptr_t i, intptr_t val) { |
144 ASSERT(i >= 0); | 134 ASSERT(i >= 0); |
145 ASSERT(i < size()); | 135 ASSERT(i < size()); |
(...skipping 19 matching lines...) Expand all Loading... |
165 intptr_t size_; | 155 intptr_t size_; |
166 intptr_t used_; | 156 intptr_t used_; |
167 intptr_t count_; | 157 intptr_t count_; |
168 | 158 |
169 DISALLOW_COPY_AND_ASSIGN(WeakTable); | 159 DISALLOW_COPY_AND_ASSIGN(WeakTable); |
170 }; | 160 }; |
171 | 161 |
172 } // namespace dart | 162 } // namespace dart |
173 | 163 |
174 #endif // RUNTIME_VM_WEAK_TABLE_H_ | 164 #endif // RUNTIME_VM_WEAK_TABLE_H_ |
OLD | NEW |