| 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 |