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

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
« no previous file with comments | « runtime/vm/vm_sources.gypi ('k') | runtime/vm/weak_table.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 < kMinSize) {
20 size = kMinSize;
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.
33 new_sz = sz / 2;
34 } else if (cnt > (sz / 2)) {
35 // Increase the capacity.
36 new_sz = sz * 2;
37 if (new_sz < sz) {
38 FATAL("Reached impossible state of having more weak table entries"
39 " than memory available for heap objects.");
40 }
41 }
42 return new WeakTable(new_sz);
43 }
44
45 intptr_t size() const { return size_; }
46 intptr_t used() const { return used_; }
47 intptr_t count() const { return count_; }
48
49 bool IsValidEntryAt(intptr_t i) const {
50 ASSERT(((ValueAt(i) == 0) &&
51 ((ObjectAt(i) == NULL) ||
52 (data_[ObjectIndex(i)] == kDeletedEntry))) ||
53 ((ValueAt(i) != 0) &&
54 (ObjectAt(i) != NULL) &&
55 (data_[ObjectIndex(i)] != kDeletedEntry)));
56 return (data_[ValueIndex(i)] != 0);
57 }
58
59 void InvalidateAt(intptr_t i) {
60 ASSERT(IsValidEntryAt(i));
61 SetValueAt(i, 0);
62 }
63
64 RawObject* ObjectAt(intptr_t i) const {
65 return reinterpret_cast<RawObject*>(data_[ObjectIndex(i)]);
66 }
67
68 intptr_t ValueAt(intptr_t i) const {
69 return data_[ValueIndex(i)];
70 }
71
72 WeakTable* SetValue(RawObject* key, intptr_t val);
73
74 intptr_t GetValue(RawObject* key) const {
75 intptr_t sz = size();
76 intptr_t idx = Hash(key) % sz;
77 RawObject* obj = ObjectAt(idx);
78 while (obj != NULL) {
79 if (obj == key) {
80 return ValueAt(idx);
81 }
82 idx = (idx + 1) % sz;
83 obj = ObjectAt(idx);
84 }
85 ASSERT(ValueAt(idx) == 0);
86 return 0;
87 }
88
89 private:
90 enum {
91 kObjectOffset = 0,
92 kValueOffset,
93 kEntrySize,
94 };
95
96 static const intptr_t kDeletedEntry = 1; // Equivalent to a tagged NULL.
97 static const intptr_t kMinSize = 8;
98
99 static intptr_t LimitFor(intptr_t size) {
100 // Maintain a maximum of 75% fill rate.
101 return 3 * (size / 4);
102 }
103 intptr_t limit() const { return LimitFor(size()); }
104
105 intptr_t index(intptr_t i) const {
106 ASSERT(i >= 0);
107 ASSERT(i < size());
108 return i * kEntrySize;
109 }
110
111 void set_used(intptr_t val) {
112 ASSERT(val <= limit());
113 used_ = val;
114 }
115
116 void set_count(intptr_t val) {
117 ASSERT(val <= limit());
118 ASSERT(val <= used());
119 count_ = val;
120 }
121
122 intptr_t ObjectIndex(intptr_t i) const {
123 return index(i) + kObjectOffset;
124 }
125
126 intptr_t ValueIndex(intptr_t i) const {
127 return index(i) + kValueOffset;
128 }
129
130 void SetObjectAt(intptr_t i, RawObject* key) {
131 data_[ObjectIndex(i)] = reinterpret_cast<intptr_t>(key);
132 }
133
134 void SetValueAt(intptr_t i, intptr_t val) {
135 // Setting a value of 0 is equivalent to invalidating the entry.
136 if (val == 0) {
137 data_[ObjectIndex(i)] = kDeletedEntry;
138 set_count(count() - 1);
139 }
140 data_[ValueIndex(i)] = val;
141 }
142
143 WeakTable* Rehash();
144
145 static intptr_t Hash(RawObject* key) {
146 return reinterpret_cast<intptr_t>(key) >> kObjectAlignmentLog2;
147 }
148
149 // data_ contains size_ tuples of key/value.
150 intptr_t* data_;
151 // size_ keeps the number of entries in data_. used_ maintains the number of
152 // non-NULL entries and will trigger rehashing if needed. count_ stores the
153 // number valid entries, and will determine the size_ after rehashing.
154 intptr_t size_;
155 intptr_t used_;
156 intptr_t count_;
157
158 DISALLOW_IMPLICIT_CONSTRUCTORS(WeakTable);
159 };
160
161 } // namespace dart
162
163 #endif // VM_WEAK_TABLE_H_
OLDNEW
« no previous file with comments | « runtime/vm/vm_sources.gypi ('k') | runtime/vm/weak_table.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698