OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 flags_ = IsPartiallyDependent::update(flags_, v); | 162 flags_ = IsPartiallyDependent::update(flags_, v); |
163 } | 163 } |
164 | 164 |
165 bool is_in_new_space_list() { | 165 bool is_in_new_space_list() { |
166 return IsInNewSpaceList::decode(flags_); | 166 return IsInNewSpaceList::decode(flags_); |
167 } | 167 } |
168 void set_in_new_space_list(bool v) { | 168 void set_in_new_space_list(bool v) { |
169 flags_ = IsInNewSpaceList::update(flags_, v); | 169 flags_ = IsInNewSpaceList::update(flags_, v); |
170 } | 170 } |
171 | 171 |
172 bool is_revivable_callback() { | |
173 return IsRevivableCallback::decode(flags_); | |
174 } | |
175 void set_revivable_callback(bool v) { | |
176 flags_ = IsRevivableCallback::update(flags_, v); | |
177 } | |
178 | |
179 bool IsNearDeath() const { | 172 bool IsNearDeath() const { |
180 // Check for PENDING to ensure correct answer when processing callbacks. | 173 // Check for PENDING to ensure correct answer when processing callbacks. |
181 return state() == PENDING || state() == NEAR_DEATH; | 174 return state() == PENDING || state() == NEAR_DEATH; |
182 } | 175 } |
183 | 176 |
184 bool IsWeak() const { return state() == WEAK; } | 177 bool IsWeak() const { return state() == WEAK; } |
185 | 178 |
186 bool IsRetainer() const { return state() != FREE; } | 179 bool IsRetainer() const { return state() != FREE; } |
187 | 180 |
188 bool IsStrongRetainer() const { return state() == NORMAL; } | 181 bool IsStrongRetainer() const { return state() == NORMAL; } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 // Accessors for next free node in the free list. | 220 // Accessors for next free node in the free list. |
228 Node* next_free() { | 221 Node* next_free() { |
229 ASSERT(state() == FREE); | 222 ASSERT(state() == FREE); |
230 return parameter_or_next_free_.next_free; | 223 return parameter_or_next_free_.next_free; |
231 } | 224 } |
232 void set_next_free(Node* value) { | 225 void set_next_free(Node* value) { |
233 ASSERT(state() == FREE); | 226 ASSERT(state() == FREE); |
234 parameter_or_next_free_.next_free = value; | 227 parameter_or_next_free_.next_free = value; |
235 } | 228 } |
236 | 229 |
237 void MakeWeak(void* parameter, | 230 void MakeWeak(void* parameter, WeakCallback weak_callback) { |
238 WeakCallback weak_callback, | 231 ASSERT(weak_callback != NULL); |
239 RevivableCallback revivable_callback) { | |
240 ASSERT((weak_callback == NULL) != (revivable_callback == NULL)); | |
241 ASSERT(state() != FREE); | 232 ASSERT(state() != FREE); |
242 set_state(WEAK); | 233 set_state(WEAK); |
243 set_parameter(parameter); | 234 set_parameter(parameter); |
244 if (weak_callback != NULL) { | 235 weak_callback_ = weak_callback; |
245 weak_callback_ = weak_callback; | |
246 set_revivable_callback(false); | |
247 } else { | |
248 weak_callback_ = | |
249 reinterpret_cast<WeakCallback>(revivable_callback); | |
250 set_revivable_callback(true); | |
251 } | |
252 } | 236 } |
253 | 237 |
254 void ClearWeakness() { | 238 void ClearWeakness() { |
255 ASSERT(state() != FREE); | 239 ASSERT(state() != FREE); |
256 set_state(NORMAL); | 240 set_state(NORMAL); |
257 set_parameter(NULL); | 241 set_parameter(NULL); |
258 } | 242 } |
259 | 243 |
260 bool PostGarbageCollectionProcessing(Isolate* isolate) { | 244 bool PostGarbageCollectionProcessing(Isolate* isolate) { |
261 if (state() != Node::PENDING) return false; | 245 if (state() != Node::PENDING) return false; |
262 if (weak_callback_ == NULL) { | 246 if (weak_callback_ == NULL) { |
263 Release(); | 247 Release(); |
264 return false; | 248 return false; |
265 } | 249 } |
266 void* par = parameter(); | 250 void* par = parameter(); |
267 set_state(NEAR_DEATH); | 251 set_state(NEAR_DEATH); |
268 set_parameter(NULL); | 252 set_parameter(NULL); |
269 | 253 |
270 Object** object = location(); | 254 Object** object = location(); |
271 { | 255 { |
272 // Check that we are not passing a finalized external string to | 256 // Check that we are not passing a finalized external string to |
273 // the callback. | 257 // the callback. |
274 ASSERT(!object_->IsExternalAsciiString() || | 258 ASSERT(!object_->IsExternalAsciiString() || |
275 ExternalAsciiString::cast(object_)->resource() != NULL); | 259 ExternalAsciiString::cast(object_)->resource() != NULL); |
276 ASSERT(!object_->IsExternalTwoByteString() || | 260 ASSERT(!object_->IsExternalTwoByteString() || |
277 ExternalTwoByteString::cast(object_)->resource() != NULL); | 261 ExternalTwoByteString::cast(object_)->resource() != NULL); |
278 // Leaving V8. | 262 // Leaving V8. |
279 VMState<EXTERNAL> state(isolate); | 263 VMState<EXTERNAL> state(isolate); |
280 HandleScope handle_scope(isolate); | 264 HandleScope handle_scope(isolate); |
281 if (is_revivable_callback()) { | 265 Handle<Object> handle(*object, isolate); |
282 RevivableCallback revivable = | 266 v8::WeakCallbackData<v8::Value, void> data( |
283 reinterpret_cast<RevivableCallback>(weak_callback_); | 267 reinterpret_cast<v8::Isolate*>(isolate), |
284 revivable(reinterpret_cast<v8::Isolate*>(isolate), | 268 v8::Utils::ToLocal(handle), |
285 reinterpret_cast<Persistent<Value>*>(&object), | 269 par); |
286 par); | 270 weak_callback_(data); |
287 } else { | |
288 Handle<Object> handle(*object, isolate); | |
289 v8::WeakCallbackData<v8::Value, void> data( | |
290 reinterpret_cast<v8::Isolate*>(isolate), | |
291 v8::Utils::ToLocal(handle), | |
292 par); | |
293 weak_callback_(data); | |
294 } | |
295 } | 271 } |
296 // Absence of explicit cleanup or revival of weak handle | 272 // Absence of explicit cleanup or revival of weak handle |
297 // in most of the cases would lead to memory leak. | 273 // in most of the cases would lead to memory leak. |
298 ASSERT(state() != NEAR_DEATH); | 274 ASSERT(state() != NEAR_DEATH); |
299 return true; | 275 return true; |
300 } | 276 } |
301 | 277 |
302 inline GlobalHandles* GetGlobalHandles(); | 278 inline GlobalHandles* GetGlobalHandles(); |
303 | 279 |
304 private: | 280 private: |
(...skipping 13 matching lines...) Expand all Loading... |
318 | 294 |
319 // Index in the containing handle block. | 295 // Index in the containing handle block. |
320 uint8_t index_; | 296 uint8_t index_; |
321 | 297 |
322 // This stores three flags (independent, partially_dependent and | 298 // This stores three flags (independent, partially_dependent and |
323 // in_new_space_list) and a State. | 299 // in_new_space_list) and a State. |
324 class NodeState: public BitField<State, 0, 4> {}; | 300 class NodeState: public BitField<State, 0, 4> {}; |
325 class IsIndependent: public BitField<bool, 4, 1> {}; | 301 class IsIndependent: public BitField<bool, 4, 1> {}; |
326 class IsPartiallyDependent: public BitField<bool, 5, 1> {}; | 302 class IsPartiallyDependent: public BitField<bool, 5, 1> {}; |
327 class IsInNewSpaceList: public BitField<bool, 6, 1> {}; | 303 class IsInNewSpaceList: public BitField<bool, 6, 1> {}; |
328 class IsRevivableCallback: public BitField<bool, 7, 1> {}; | |
329 | 304 |
330 uint8_t flags_; | 305 uint8_t flags_; |
331 | 306 |
332 // Handle specific callback - might be a weak reference in disguise. | 307 // Handle specific callback - might be a weak reference in disguise. |
333 WeakCallback weak_callback_; | 308 WeakCallback weak_callback_; |
334 | 309 |
335 // Provided data for callback. In FREE state, this is used for | 310 // Provided data for callback. In FREE state, this is used for |
336 // the free list link. | 311 // the free list link. |
337 union { | 312 union { |
338 void* parameter; | 313 void* parameter; |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 } | 490 } |
516 | 491 |
517 | 492 |
518 void GlobalHandles::Destroy(Object** location) { | 493 void GlobalHandles::Destroy(Object** location) { |
519 if (location != NULL) Node::FromLocation(location)->Release(); | 494 if (location != NULL) Node::FromLocation(location)->Release(); |
520 } | 495 } |
521 | 496 |
522 | 497 |
523 void GlobalHandles::MakeWeak(Object** location, | 498 void GlobalHandles::MakeWeak(Object** location, |
524 void* parameter, | 499 void* parameter, |
525 WeakCallback weak_callback, | 500 WeakCallback weak_callback) { |
526 RevivableCallback revivable_callback) { | 501 Node::FromLocation(location)->MakeWeak(parameter, weak_callback); |
527 Node::FromLocation(location)->MakeWeak( | |
528 parameter, weak_callback, revivable_callback); | |
529 } | 502 } |
530 | 503 |
531 | 504 |
532 void GlobalHandles::ClearWeakness(Object** location) { | 505 void GlobalHandles::ClearWeakness(Object** location) { |
533 Node::FromLocation(location)->ClearWeakness(); | 506 Node::FromLocation(location)->ClearWeakness(); |
534 } | 507 } |
535 | 508 |
536 | 509 |
537 void GlobalHandles::MarkIndependent(Object** location) { | 510 void GlobalHandles::MarkIndependent(Object** location) { |
538 Node::FromLocation(location)->MarkIndependent(); | 511 Node::FromLocation(location)->MarkIndependent(); |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 ASSERT_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); | 1084 ASSERT_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); |
1112 blocks_[block][offset] = object; | 1085 blocks_[block][offset] = object; |
1113 if (isolate->heap()->InNewSpace(object)) { | 1086 if (isolate->heap()->InNewSpace(object)) { |
1114 new_space_indices_.Add(size_); | 1087 new_space_indices_.Add(size_); |
1115 } | 1088 } |
1116 *index = size_++; | 1089 *index = size_++; |
1117 } | 1090 } |
1118 | 1091 |
1119 | 1092 |
1120 } } // namespace v8::internal | 1093 } } // namespace v8::internal |
OLD | NEW |