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

Side by Side Diff: src/global-handles.h

Issue 155540: Fasten global handles allocation. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 4 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 | « no previous file | src/global-handles.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2007-2008 the V8 project authors. All rights reserved. 1 // Copyright 2007-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 ObjectGroup() : objects_(4) {} 50 ObjectGroup() : objects_(4) {}
51 explicit ObjectGroup(size_t capacity) : objects_(capacity) {} 51 explicit ObjectGroup(size_t capacity) : objects_(capacity) {}
52 52
53 List<Object**> objects_; 53 List<Object**> objects_;
54 }; 54 };
55 55
56 56
57 class GlobalHandles : public AllStatic { 57 class GlobalHandles : public AllStatic {
58 public: 58 public:
59 // Creates a new global handle that is alive until Destroy is called. 59 // Creates a new global handle that is alive until Destroy is called.
60 static Handle<Object> Create(Object* value); 60 static Handle<Object> Create(Object* value) {
61 Counters::global_handles.Increment();
62 Node* result;
63 if (first_free()) {
64 // Take the first node in the free list.
65 result = first_free();
66 set_first_free(result->next_free());
67 } else if (first_deallocated()) {
68 // Next try deallocated list
69 result = first_deallocated();
70 set_first_deallocated(result->next_free());
71 set_head(result);
72 } else {
73 // Allocate a new node.
74 result = pool_.Allocate();
75 result->set_next(head());
76 set_head(result);
77 }
78 result->Initialize(value);
79 return result->handle();
80 }
81
61 82
62 // Destroy a global handle. 83 // Destroy a global handle.
63 static void Destroy(Object** location); 84 static void Destroy(Object** location);
64 85
65 // Make the global handle weak and set the callback parameter for the 86 // Make the global handle weak and set the callback parameter for the
66 // handle. When the garbage collector recognizes that only weak global 87 // handle. When the garbage collector recognizes that only weak global
67 // handles point to an object the handles are cleared and the callback 88 // handles point to an object the handles are cleared and the callback
68 // function is invoked (for each handle) with the handle and corresponding 89 // function is invoked (for each handle) with the handle and corresponding
69 // parameter as arguments. Note: cleared means set to Smi::FromInt(0). The 90 // parameter as arguments. Note: cleared means set to Smi::FromInt(0). The
70 // reason is that Smi::FromInt(0) does not change during garage collection. 91 // reason is that Smi::FromInt(0) does not change during garage collection.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 137
117 // Tear down the global handle structure. 138 // Tear down the global handle structure.
118 static void TearDown(); 139 static void TearDown();
119 140
120 #ifdef DEBUG 141 #ifdef DEBUG
121 static void PrintStats(); 142 static void PrintStats();
122 static void Print(); 143 static void Print();
123 #endif 144 #endif
124 private: 145 private:
125 // Internal node structure, one for each global handle. 146 // Internal node structure, one for each global handle.
126 class Node; 147 class Node {
148 public:
149 // Transition diagram:
150 // NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, DESTROYED }
151 enum State {
152 NORMAL, // Normal global handle.
153 WEAK, // Flagged as weak but not yet finalized.
154 PENDING, // Has been recognized as only reachable by weak handles.
155 NEAR_DEATH, // Callback has informed the handle is near death.
156 DESTROYED
157 };
158
159 Node() { state_ = DESTROYED; }
160
161 explicit Node(Object* object) {
162 Initialize(object);
163 // Initialize link structure.
164 next_ = NULL;
165 }
166
167 ~Node() {
168 if (state_ != DESTROYED) Destroy();
169 #ifdef DEBUG
170 // Zap the values for eager trapping.
171 object_ = NULL;
172 next_ = NULL;
173 parameter_or_next_free_.next_free = NULL;
174 #endif
175 }
176
177 void Initialize(Object* object) {
178 // Set the initial value of the handle.
179 object_ = object;
180 state_ = NORMAL;
181 parameter_or_next_free_.parameter = NULL;
182 callback_ = NULL;
183 }
184
185 void Destroy();
186
187 // Accessors for next_.
188 Node* next() { return next_; }
189 void set_next(Node* value) { next_ = value; }
190 Node** next_addr() { return &next_; }
191
192 // Accessors for next free node in the free list.
193 Node* next_free() {
194 ASSERT(state_ == DESTROYED);
195 return parameter_or_next_free_.next_free;
196 }
197 void set_next_free(Node* value) {
198 ASSERT(state_ == DESTROYED);
199 parameter_or_next_free_.next_free = value;
200 }
201
202 // Returns a link from the handle.
203 static Node* FromLocation(Object** location) {
204 ASSERT(OFFSET_OF(Node, object_) == 0);
205 return reinterpret_cast<Node*>(location);
206 }
207
208 // Returns the handle.
209 Handle<Object> handle() { return Handle<Object>(&object_); }
210
211 // Make this handle weak.
212 void MakeWeak(void* parameter, WeakReferenceCallback callback);
213 void ClearWeakness();
214
215 bool IsNearDeath() {
216 // Check for PENDING to ensure correct answer when processing callbacks.
217 return state_ == PENDING || state_ == NEAR_DEATH;
218 }
219
220 bool IsWeak() {
221 return state_ == WEAK;
222 }
223
224 // Returns the id for this weak handle.
225 void set_parameter(void* parameter) {
226 ASSERT(state_ != DESTROYED);
227 parameter_or_next_free_.parameter = parameter;
228 }
229 void* parameter() {
230 ASSERT(state_ != DESTROYED);
231 return parameter_or_next_free_.parameter;
232 }
233
234 // Returns the callback for this weak handle.
235 WeakReferenceCallback callback() { return callback_; }
236
237 void PostGarbageCollectionProcessing();
238
239 // Place the handle address first to avoid offset computation.
240 Object* object_; // Storage for object pointer.
241
242 State state_;
243
244 private:
245 // Handle specific callback.
246 WeakReferenceCallback callback_;
247 // Provided data for callback. In DESTROYED state, this is used for
248 // the free list link.
249 union {
250 void* parameter;
251 Node* next_free;
252 } parameter_or_next_free_;
253
254 // Linkage for the list.
255 Node* next_;
256
257 public:
258 TRACK_MEMORY("GlobalHandles::Node")
259 };
260
261
262 class Pool BASE_EMBEDDED {
263 public:
264 Pool() {
265 current_ = new Chunk();
266 current_->previous = NULL;
267 next_ = current_->nodes;
268 limit_ = current_->nodes + kNodesPerChunk;
269 }
270
271 Node* Allocate() {
272 if (next_ < limit_) {
273 return next_++;
274 }
275 return SlowAllocate();
276 }
277
278 void Release();
279
280 private:
281 static const int kNodesPerChunk = 8192;
282 struct Chunk : public Malloced {
283 Chunk* previous;
284 Node nodes[kNodesPerChunk];
285 };
286
287 Node* SlowAllocate();
288
289 Chunk* current_;
290 Node* next_;
291 Node* limit_;
292 };
293
294 static Pool pool_;
295
127 296
128 // Field always containing the number of weak and near-death handles. 297 // Field always containing the number of weak and near-death handles.
129 static int number_of_weak_handles_; 298 static int number_of_weak_handles_;
130 299
131 // Field always containing the number of weak and near-death handles 300 // Field always containing the number of weak and near-death handles
132 // to global objects. These objects are also included in 301 // to global objects. These objects are also included in
133 // number_of_weak_handles_. 302 // number_of_weak_handles_.
134 static int number_of_global_object_weak_handles_; 303 static int number_of_global_object_weak_handles_;
135 304
136 // Global handles are kept in a single linked list pointed to by head_. 305 // Global handles are kept in a single linked list pointed to by head_.
137 static Node* head_; 306 static Node* head_;
138 static Node* head() { return head_; } 307 static Node* head() { return head_; }
139 static void set_head(Node* value) { head_ = value; } 308 static void set_head(Node* value) { head_ = value; }
140 309
141 // Free list for DESTROYED global handles not yet deallocated. 310 // Free list for DESTROYED global handles not yet deallocated.
142 static Node* first_free_; 311 static Node* first_free_;
143 static Node* first_free() { return first_free_; } 312 static Node* first_free() { return first_free_; }
144 static void set_first_free(Node* value) { first_free_ = value; } 313 static void set_first_free(Node* value) { first_free_ = value; }
314
315 // List of deallocated nodes. Even though they are deallocated,
316 // they keep correct next pointers, so allocating it back is just a matter
317 // of setting head to it (and ajusting |first_deallocated_|)
318 static Node* first_deallocated_;
319 static Node* first_deallocated() { return first_deallocated_; }
320 static void set_first_deallocated(Node* value) {
321 first_deallocated_ = value;
322 }
145 }; 323 };
146 324
147 325
148 } } // namespace v8::internal 326 } } // namespace v8::internal
149 327
150 #endif // V8_GLOBAL_HANDLES_H_ 328 #endif // V8_GLOBAL_HANDLES_H_
OLDNEW
« no previous file with comments | « no previous file | src/global-handles.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698