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

Side by Side Diff: runtime/vm/weak_table.h

Issue 17992002: - Add a WeakTable to the VM. This is used to remember the (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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 #ifndef VM_WEAK_TABLE_H_
6 #define VM_WEAK_TABLE_H_
7
8 #include "vm/globals.h"
9
10 #include "platform/assert.h"
11 #include "vm/raw_object.h"
12
13 namespace dart {
14
15 class WeakTable {
16 public:
17 explicit WeakTable(intptr_t size) : used_(0), count_(0) {
18 ASSERT(size >= 0);
19 if (size < 8) {
20 size = 8;
21 }
22 data_ = reinterpret_cast<intptr_t*>(calloc(size, kEntrySize * kWordSize));
23 size_ = size;
24 }
25
26 static WeakTable* NewFrom(WeakTable* original) {
27 intptr_t cnt = original->count();
28 intptr_t sz = original->size();
29 intptr_t new_sz = sz;
30
31 if (cnt <= (sz / 4)) {
32 // Reduce the capacity.
siva 2013/06/27 22:11:33 ASSERT(sz > 1);
Ivan Posva 2013/06/27 23:59:12 sz of zero is a legal value.
33 new_sz = sz / 2;
34 } else if (cnt > (sz / 2)) {
35 // Increase the capacity.
36 new_sz = sz * 2;
siva 2013/06/27 22:11:33 we should protect against overflows here. Maybe so
Ivan Posva 2013/06/27 23:59:12 Done.
37 }
38 return new WeakTable(new_sz);
39 }
40
41 intptr_t size() const { return size_; }
42 intptr_t used() const { return used_; }
43 intptr_t count() const { return count_; }
44
45 bool IsValidEntryAt(intptr_t i) {
siva 2013/06/27 22:11:33 const
Ivan Posva 2013/06/27 23:59:12 Done.
46 ASSERT(((ValueAt(i) == 0) &&
47 ((ObjectAt(i) == NULL) ||
48 (data_[ObjectIndex(i)] == kDeletedEntry))) ||
49 ((ValueAt(i) != 0) &&
50 (ObjectAt(i) != NULL) &&
51 (data_[ObjectIndex(i)] != kDeletedEntry)));
52 return (data_[ValueIndex(i)] != 0);
53 }
54
55 void InvalidateAt(intptr_t i) {
56 ASSERT(IsValidEntryAt(i));
57 SetValueAt(i, 0);
58 }
59
60 RawObject* ObjectAt(intptr_t i) {
siva 2013/06/27 22:11:33 const Here and some more functions below.
Ivan Posva 2013/06/27 23:59:12 Done.
61 return reinterpret_cast<RawObject*>(data_[ObjectIndex(i)]);
62 }
63
64 intptr_t ValueAt(intptr_t i) {
65 return data_[ValueIndex(i)];
66 }
67
68 WeakTable* SetValue(RawObject* key, intptr_t val);
69
70 intptr_t GetValue(RawObject* key) {
71 intptr_t sz = size();
72 intptr_t idx = Hash(key) % sz;
73 RawObject* obj = ObjectAt(idx);
74 while (obj != NULL) {
75 if (obj == key) {
76 return ValueAt(idx);
77 }
78 idx = (idx + 1) % sz;
79 obj = ObjectAt(idx);
80 }
81 ASSERT(ValueAt(idx) == 0);
82 return 0;
83 }
84
85 private:
86 enum {
87 kObjectOffset = 0,
88 kValueOffset,
89 kEntrySize,
90 };
91
92 static const intptr_t kDeletedEntry = 1; // Equivalent to a tagged NULL.
93
94 static intptr_t LimitFor(intptr_t size) { return 3 * (size / 4); }
siva 2013/06/27 22:11:33 Use names constants instead of 3, 4 etc. here and
Ivan Posva 2013/06/27 23:59:12 Added a kMinSize and a comment in LimitFor, as 3 a
95 intptr_t limit() const { return LimitFor(size()); }
96
97 intptr_t index(intptr_t i) {
98 ASSERT(i >= 0);
99 ASSERT(i < size());
100 return i * kEntrySize;
101 }
102
103 void set_used(intptr_t val) {
104 ASSERT(val <= limit());
105 used_ = val;
106 }
107
108 void set_count(intptr_t val) {
109 ASSERT(val <= limit());
110 ASSERT(val <= used());
111 count_ = val;
112 }
113
114 intptr_t ObjectIndex(intptr_t i) {
115 return index(i) + kObjectOffset;
116 }
117
118 intptr_t ValueIndex(intptr_t i) {
119 return index(i) + kValueOffset;
120 }
121
122 void SetObjectAt(intptr_t i, RawObject* key) {
123 data_[ObjectIndex(i)] = reinterpret_cast<intptr_t>(key);
124 }
125
126 void SetValueAt(intptr_t i, intptr_t val) {
127 // Setting a value of 0 is equivalent to invalidating the entry.
siva 2013/06/27 22:11:33 The comment here states setting a value of 0 is eq
128 if (val == 0) {
129 data_[ObjectIndex(i)] = kDeletedEntry;
130 set_count(count() - 1);
131 }
132 data_[ValueIndex(i)] = val;
133 }
134
135 WeakTable* Rehash();
136
137 static intptr_t Hash(RawObject* key) {
138 return reinterpret_cast<intptr_t>(key) >> kObjectAlignmentLog2;
139 }
140
141 // data_ contains size_ tuples of key/value.
142 intptr_t* data_;
143 // size_ keeps the number of entries in data_. used_ maintains the number of
144 // non-NULL entries and will trigger rehashing if needed. count_ stores the
145 // number valid entries, and will determine the size_ after rehashing.
146 intptr_t size_;
147 intptr_t used_;
148 intptr_t count_;
siva 2013/06/27 22:11:33 Missing the DISALLOW stuff...
Ivan Posva 2013/06/27 23:59:12 Done.
149 };
150
151 } // namespace dart
152
153 #endif // VM_WEAK_TABLE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698