| 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 |