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

Unified Diff: runtime/vm/weak_table.cc

Issue 18826007: Reland r24563 and r24564 with fixes cumbersome API leading to leaks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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/weak_table.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/weak_table.cc
===================================================================
--- runtime/vm/weak_table.cc (revision 24610)
+++ runtime/vm/weak_table.cc (working copy)
@@ -9,21 +9,41 @@
namespace dart {
-WeakTable* WeakTable::SetValue(RawObject* key, intptr_t val) {
- intptr_t sz = size();
- intptr_t idx = Hash(key) % sz;
+intptr_t WeakTable::SizeFor(intptr_t count, intptr_t size) {
+ intptr_t result = size;
+ if (count <= (size / 4)) {
+ // Reduce the capacity.
+ result = size / 2;
+ } else {
+ // Increase the capacity.
+ result = size * 2;
+ if (result < size) {
+ FATAL("Reached impossible state of having more weak table entries"
+ " than memory available for heap objects.");
+ }
+ }
+ if (result < kMinSize) {
+ result = kMinSize;
+ }
+ return result;
+}
+
+
+void WeakTable::SetValue(RawObject* key, intptr_t val) {
+ intptr_t mask = size() - 1;
+ intptr_t idx = Hash(key) & mask;
intptr_t empty_idx = -1;
RawObject* obj = ObjectAt(idx);
while (obj != NULL) {
if (obj == key) {
SetValueAt(idx, val);
- return this;
+ return;
} else if ((empty_idx < 0) &&
(reinterpret_cast<intptr_t>(obj) == kDeletedEntry)) {
empty_idx = idx; // Insert at this location if not found.
}
- idx = (idx + 1) % sz;
+ idx = (idx + 1) & mask;
obj = ObjectAt(idx);
}
@@ -31,7 +51,7 @@
// Do not enter an invalid value. Associating 0 with a key deletes it from
// this weak table above in SetValueAt. If the key was not present in the
// weak table we are done.
- return this;
+ return;
}
if (empty_idx >= 0) {
@@ -50,23 +70,46 @@
// Rehash if needed to ensure that there are empty slots available.
if (used_ >= limit()) {
- return Rehash();
+ Rehash();
}
- return this;
}
-WeakTable* WeakTable::Rehash() {
- intptr_t sz = size();
- WeakTable* result = NewFrom(this);
+void WeakTable::Rehash() {
+ intptr_t old_size = size();
+ intptr_t* old_data = data_;
- for (intptr_t i = 0; i < sz; i++) {
+ intptr_t new_size = SizeFor(count(), size());
+ ASSERT(Utils::IsPowerOfTwo(new_size));
+ intptr_t* new_data = reinterpret_cast<intptr_t*>(
+ calloc(new_size, kEntrySize * kWordSize));
+
+ intptr_t mask = new_size - 1;
+ set_used(0);
+ for (intptr_t i = 0; i < old_size; i++) {
if (IsValidEntryAt(i)) {
- WeakTable* temp = result->SetValue(ObjectAt(i), ValueAt(i));
- ASSERT(temp == result);
+ // Find the new hash location for this entry.
+ RawObject* key = ObjectAt(i);
+ intptr_t idx = Hash(key) & mask;
+ RawObject* obj = reinterpret_cast<RawObject*>(new_data[ObjectIndex(idx)]);
+ while (obj != NULL) {
+ ASSERT(obj != key); // Duplicate entry is not expected.
+ idx = (idx + 1) & mask;
+ obj = reinterpret_cast<RawObject*>(new_data[ObjectIndex(idx)]);
+ }
+
+ new_data[ObjectIndex(idx)] = reinterpret_cast<intptr_t>(key);
+ new_data[ValueIndex(idx)] = ValueAt(i);
+ set_used(used() + 1);
}
}
- return result;
+ // We should only have used valid entries.
+ ASSERT(used() == count());
+
+ // Switch to using the newly allocated backing store.
+ size_ = new_size;
+ data_ = new_data;
+ free(old_data);
}
} // namespace dart
« no previous file with comments | « runtime/vm/weak_table.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698