| 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 23 matching lines...) Expand all Loading... |
| 34 | 34 |
| 35 namespace v8 { | 35 namespace v8 { |
| 36 namespace internal { | 36 namespace internal { |
| 37 | 37 |
| 38 class GlobalHandles::Node : public Malloced { | 38 class GlobalHandles::Node : public Malloced { |
| 39 public: | 39 public: |
| 40 | 40 |
| 41 void Initialize(Object* object) { | 41 void Initialize(Object* object) { |
| 42 // Set the initial value of the handle. | 42 // Set the initial value of the handle. |
| 43 object_ = object; | 43 object_ = object; |
| 44 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; |
| 44 state_ = NORMAL; | 45 state_ = NORMAL; |
| 45 parameter_or_next_free_.parameter = NULL; | 46 parameter_or_next_free_.parameter = NULL; |
| 46 callback_ = NULL; | 47 callback_ = NULL; |
| 47 } | 48 } |
| 48 | 49 |
| 49 Node() { | 50 Node() { |
| 50 state_ = DESTROYED; | 51 state_ = DESTROYED; |
| 51 } | 52 } |
| 52 | 53 |
| 53 explicit Node(Object* object) { | 54 explicit Node(Object* object) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 | 131 |
| 131 bool IsNearDeath() { | 132 bool IsNearDeath() { |
| 132 // Check for PENDING to ensure correct answer when processing callbacks. | 133 // Check for PENDING to ensure correct answer when processing callbacks. |
| 133 return state_ == PENDING || state_ == NEAR_DEATH; | 134 return state_ == PENDING || state_ == NEAR_DEATH; |
| 134 } | 135 } |
| 135 | 136 |
| 136 bool IsWeak() { | 137 bool IsWeak() { |
| 137 return state_ == WEAK; | 138 return state_ == WEAK; |
| 138 } | 139 } |
| 139 | 140 |
| 141 bool CanBeRetainer() { |
| 142 return state_ != DESTROYED && state_ != NEAR_DEATH; |
| 143 } |
| 144 |
| 145 void SetWrapperClassId(uint16_t class_id) { |
| 146 class_id_ = class_id; |
| 147 } |
| 148 |
| 140 // Returns the id for this weak handle. | 149 // Returns the id for this weak handle. |
| 141 void set_parameter(void* parameter) { | 150 void set_parameter(void* parameter) { |
| 142 ASSERT(state_ != DESTROYED); | 151 ASSERT(state_ != DESTROYED); |
| 143 parameter_or_next_free_.parameter = parameter; | 152 parameter_or_next_free_.parameter = parameter; |
| 144 } | 153 } |
| 145 void* parameter() { | 154 void* parameter() { |
| 146 ASSERT(state_ != DESTROYED); | 155 ASSERT(state_ != DESTROYED); |
| 147 return parameter_or_next_free_.parameter; | 156 return parameter_or_next_free_.parameter; |
| 148 } | 157 } |
| 149 | 158 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 } | 192 } |
| 184 // Absense of explicit cleanup or revival of weak handle | 193 // Absense of explicit cleanup or revival of weak handle |
| 185 // in most of the cases would lead to memory leak. | 194 // in most of the cases would lead to memory leak. |
| 186 ASSERT(state_ != NEAR_DEATH); | 195 ASSERT(state_ != NEAR_DEATH); |
| 187 return true; | 196 return true; |
| 188 } | 197 } |
| 189 | 198 |
| 190 // Place the handle address first to avoid offset computation. | 199 // Place the handle address first to avoid offset computation. |
| 191 Object* object_; // Storage for object pointer. | 200 Object* object_; // Storage for object pointer. |
| 192 | 201 |
| 202 uint16_t class_id_; |
| 203 |
| 193 // Transition diagram: | 204 // Transition diagram: |
| 194 // NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, DESTROYED } | 205 // NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, DESTROYED } |
| 195 enum State { | 206 enum State { |
| 196 NORMAL, // Normal global handle. | 207 NORMAL, // Normal global handle. |
| 197 WEAK, // Flagged as weak but not yet finalized. | 208 WEAK, // Flagged as weak but not yet finalized. |
| 198 PENDING, // Has been recognized as only reachable by weak handles. | 209 PENDING, // Has been recognized as only reachable by weak handles. |
| 199 NEAR_DEATH, // Callback has informed the handle is near death. | 210 NEAR_DEATH, // Callback has informed the handle is near death. |
| 200 DESTROYED | 211 DESTROYED |
| 201 }; | 212 }; |
| 202 State state_; | 213 State state_ : 3; |
| 203 | 214 |
| 204 private: | 215 private: |
| 205 // Handle specific callback. | 216 // Handle specific callback. |
| 206 WeakReferenceCallback callback_; | 217 WeakReferenceCallback callback_; |
| 207 // Provided data for callback. In DESTROYED state, this is used for | 218 // Provided data for callback. In DESTROYED state, this is used for |
| 208 // the free list link. | 219 // the free list link. |
| 209 union { | 220 union { |
| 210 void* parameter; | 221 void* parameter; |
| 211 Node* next_free; | 222 Node* next_free; |
| 212 } parameter_or_next_free_; | 223 } parameter_or_next_free_; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 bool GlobalHandles::IsNearDeath(Object** location) { | 341 bool GlobalHandles::IsNearDeath(Object** location) { |
| 331 return Node::FromLocation(location)->IsNearDeath(); | 342 return Node::FromLocation(location)->IsNearDeath(); |
| 332 } | 343 } |
| 333 | 344 |
| 334 | 345 |
| 335 bool GlobalHandles::IsWeak(Object** location) { | 346 bool GlobalHandles::IsWeak(Object** location) { |
| 336 return Node::FromLocation(location)->IsWeak(); | 347 return Node::FromLocation(location)->IsWeak(); |
| 337 } | 348 } |
| 338 | 349 |
| 339 | 350 |
| 351 void GlobalHandles::SetWrapperClassId(Object** location, uint16_t class_id) { |
| 352 Node::FromLocation(location)->SetWrapperClassId(class_id); |
| 353 } |
| 354 |
| 355 |
| 340 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { | 356 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { |
| 341 // Traversal of GC roots in the global handle list that are marked as | 357 // Traversal of GC roots in the global handle list that are marked as |
| 342 // WEAK or PENDING. | 358 // WEAK or PENDING. |
| 343 for (Node* current = head_; current != NULL; current = current->next()) { | 359 for (Node* current = head_; current != NULL; current = current->next()) { |
| 344 if (current->state_ == Node::WEAK | 360 if (current->state_ == Node::WEAK |
| 345 || current->state_ == Node::PENDING | 361 || current->state_ == Node::PENDING |
| 346 || current->state_ == Node::NEAR_DEATH) { | 362 || current->state_ == Node::NEAR_DEATH) { |
| 347 v->VisitPointer(¤t->object_); | 363 v->VisitPointer(¤t->object_); |
| 348 } | 364 } |
| 349 } | 365 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 | 444 |
| 429 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) { | 445 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) { |
| 430 for (Node* current = head_; current != NULL; current = current->next()) { | 446 for (Node* current = head_; current != NULL; current = current->next()) { |
| 431 if (current->state_ != Node::DESTROYED) { | 447 if (current->state_ != Node::DESTROYED) { |
| 432 v->VisitPointer(¤t->object_); | 448 v->VisitPointer(¤t->object_); |
| 433 } | 449 } |
| 434 } | 450 } |
| 435 } | 451 } |
| 436 | 452 |
| 437 | 453 |
| 454 void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) { |
| 455 for (Node* current = head_; current != NULL; current = current->next()) { |
| 456 if (current->class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId && |
| 457 current->CanBeRetainer()) { |
| 458 v->VisitEmbedderReference(¤t->object_, current->class_id_); |
| 459 } |
| 460 } |
| 461 } |
| 462 |
| 463 |
| 438 void GlobalHandles::TearDown() { | 464 void GlobalHandles::TearDown() { |
| 439 // Reset all the lists. | 465 // Reset all the lists. |
| 440 set_head(NULL); | 466 set_head(NULL); |
| 441 set_first_free(NULL); | 467 set_first_free(NULL); |
| 442 set_first_deallocated(NULL); | 468 set_first_deallocated(NULL); |
| 443 pool_.Release(); | 469 pool_.Release(); |
| 444 } | 470 } |
| 445 | 471 |
| 446 | 472 |
| 447 int GlobalHandles::number_of_weak_handles_ = 0; | 473 int GlobalHandles::number_of_weak_handles_ = 0; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 } | 534 } |
| 509 | 535 |
| 510 #endif | 536 #endif |
| 511 | 537 |
| 512 List<ObjectGroup*>* GlobalHandles::ObjectGroups() { | 538 List<ObjectGroup*>* GlobalHandles::ObjectGroups() { |
| 513 // Lazily initialize the list to avoid startup time static constructors. | 539 // Lazily initialize the list to avoid startup time static constructors. |
| 514 static List<ObjectGroup*> groups(4); | 540 static List<ObjectGroup*> groups(4); |
| 515 return &groups; | 541 return &groups; |
| 516 } | 542 } |
| 517 | 543 |
| 518 void GlobalHandles::AddGroup(Object*** handles, size_t length) { | 544 void GlobalHandles::AddGroup(Object*** handles, |
| 519 ObjectGroup* new_entry = new ObjectGroup(length); | 545 size_t length, |
| 546 v8::RetainedObjectInfo* info) { |
| 547 ObjectGroup* new_entry = new ObjectGroup(length, info); |
| 520 for (size_t i = 0; i < length; ++i) | 548 for (size_t i = 0; i < length; ++i) |
| 521 new_entry->objects_.Add(handles[i]); | 549 new_entry->objects_.Add(handles[i]); |
| 522 ObjectGroups()->Add(new_entry); | 550 ObjectGroups()->Add(new_entry); |
| 523 } | 551 } |
| 524 | 552 |
| 525 | 553 |
| 526 void GlobalHandles::RemoveObjectGroups() { | 554 void GlobalHandles::RemoveObjectGroups() { |
| 527 List<ObjectGroup*>* object_groups = ObjectGroups(); | 555 List<ObjectGroup*>* object_groups = ObjectGroups(); |
| 528 for (int i = 0; i< object_groups->length(); i++) { | 556 for (int i = 0; i< object_groups->length(); i++) { |
| 529 delete object_groups->at(i); | 557 delete object_groups->at(i); |
| 530 } | 558 } |
| 531 object_groups->Clear(); | 559 object_groups->Clear(); |
| 532 } | 560 } |
| 533 | 561 |
| 534 } } // namespace v8::internal | 562 } } // namespace v8::internal |
| OLD | NEW |