| 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 14 matching lines...) Expand all Loading... |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "global-handles.h" | 31 #include "global-handles.h" |
| 32 | 32 |
| 33 namespace v8 { | 33 namespace v8 { |
| 34 namespace internal { | 34 namespace internal { |
| 35 | 35 class GlobalHandlesData::Node : public Malloced { |
| 36 class GlobalHandles::Node : public Malloced { | |
| 37 public: | 36 public: |
| 38 | 37 |
| 39 void Initialize(Object* object) { | 38 void Initialize(Object* object) { |
| 40 // Set the initial value of the handle. | 39 // Set the initial value of the handle. |
| 41 object_ = object; | 40 object_ = object; |
| 42 state_ = NORMAL; | 41 state_ = NORMAL; |
| 43 parameter_or_next_free_.parameter = NULL; | 42 parameter_or_next_free_.parameter = NULL; |
| 44 callback_ = NULL; | 43 callback_ = NULL; |
| 45 } | 44 } |
| 46 | 45 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 59 #ifdef DEBUG | 58 #ifdef DEBUG |
| 60 // Zap the values for eager trapping. | 59 // Zap the values for eager trapping. |
| 61 object_ = NULL; | 60 object_ = NULL; |
| 62 next_ = NULL; | 61 next_ = NULL; |
| 63 parameter_or_next_free_.next_free = NULL; | 62 parameter_or_next_free_.next_free = NULL; |
| 64 #endif | 63 #endif |
| 65 } | 64 } |
| 66 | 65 |
| 67 void Destroy() { | 66 void Destroy() { |
| 68 if (state_ == WEAK || IsNearDeath()) { | 67 if (state_ == WEAK || IsNearDeath()) { |
| 69 GlobalHandles::number_of_weak_handles_--; | 68 v8_context()->global_handles_data_.number_of_weak_handles_--; |
| 70 if (object_->IsJSGlobalObject()) { | 69 if (object_->IsJSGlobalObject()) { |
| 71 GlobalHandles::number_of_global_object_weak_handles_--; | 70 v8_context()->global_handles_data_. |
| 71 number_of_global_object_weak_handles_--; |
| 72 } | 72 } |
| 73 } | 73 } |
| 74 state_ = DESTROYED; | 74 state_ = DESTROYED; |
| 75 } | 75 } |
| 76 | 76 |
| 77 // Accessors for next_. | 77 // Accessors for next_. |
| 78 Node* next() { return next_; } | 78 Node* next() { return next_; } |
| 79 void set_next(Node* value) { next_ = value; } | 79 void set_next(Node* value) { next_ = value; } |
| 80 Node** next_addr() { return &next_; } | 80 Node** next_addr() { return &next_; } |
| 81 | 81 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Returns the handle. | 98 // Returns the handle. |
| 99 Handle<Object> handle() { return Handle<Object>(&object_); } | 99 Handle<Object> handle() { return Handle<Object>(&object_); } |
| 100 | 100 |
| 101 // Make this handle weak. | 101 // Make this handle weak. |
| 102 void MakeWeak(void* parameter, WeakReferenceCallback callback) { | 102 void MakeWeak(void* parameter, WeakReferenceCallback callback) { |
| 103 LOG(HandleEvent("GlobalHandle::MakeWeak", handle().location())); | 103 LOG(HandleEvent("GlobalHandle::MakeWeak", handle().location())); |
| 104 ASSERT(state_ != DESTROYED); | 104 ASSERT(state_ != DESTROYED); |
| 105 if (state_ != WEAK && !IsNearDeath()) { | 105 if (state_ != WEAK && !IsNearDeath()) { |
| 106 GlobalHandles::number_of_weak_handles_++; | 106 v8_context()->global_handles_data_.number_of_weak_handles_++; |
| 107 if (object_->IsJSGlobalObject()) { | 107 if (object_->IsJSGlobalObject()) { |
| 108 GlobalHandles::number_of_global_object_weak_handles_++; | 108 v8_context()->global_handles_data_. |
| 109 number_of_global_object_weak_handles_++; |
| 109 } | 110 } |
| 110 } | 111 } |
| 111 state_ = WEAK; | 112 state_ = WEAK; |
| 112 set_parameter(parameter); | 113 set_parameter(parameter); |
| 113 callback_ = callback; | 114 callback_ = callback; |
| 114 } | 115 } |
| 115 | 116 |
| 116 void ClearWeakness() { | 117 void ClearWeakness() { |
| 117 LOG(HandleEvent("GlobalHandle::ClearWeakness", handle().location())); | 118 LOG(HandleEvent("GlobalHandle::ClearWeakness", handle().location())); |
| 118 ASSERT(state_ != DESTROYED); | 119 ASSERT(state_ != DESTROYED); |
| 119 if (state_ == WEAK || IsNearDeath()) { | 120 if (state_ == WEAK || IsNearDeath()) { |
| 120 GlobalHandles::number_of_weak_handles_--; | 121 v8_context()->global_handles_data_.number_of_weak_handles_--; |
| 121 if (object_->IsJSGlobalObject()) { | 122 if (object_->IsJSGlobalObject()) { |
| 122 GlobalHandles::number_of_global_object_weak_handles_--; | 123 v8_context()->global_handles_data_. |
| 124 number_of_global_object_weak_handles_--; |
| 123 } | 125 } |
| 124 } | 126 } |
| 125 state_ = NORMAL; | 127 state_ = NORMAL; |
| 126 set_parameter(NULL); | 128 set_parameter(NULL); |
| 127 } | 129 } |
| 128 | 130 |
| 129 bool IsNearDeath() { | 131 bool IsNearDeath() { |
| 130 // Check for PENDING to ensure correct answer when processing callbacks. | 132 // Check for PENDING to ensure correct answer when processing callbacks. |
| 131 return state_ == PENDING || state_ == NEAR_DEATH; | 133 return state_ == PENDING || state_ == NEAR_DEATH; |
| 132 } | 134 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 157 // The callback function is resolved as late as possible to preserve old | 159 // The callback function is resolved as late as possible to preserve old |
| 158 // behavior. | 160 // behavior. |
| 159 WeakReferenceCallback func = callback(); | 161 WeakReferenceCallback func = callback(); |
| 160 if (func == NULL) return false; | 162 if (func == NULL) return false; |
| 161 | 163 |
| 162 v8::Persistent<v8::Object> object = ToApi<v8::Object>(handle()); | 164 v8::Persistent<v8::Object> object = ToApi<v8::Object>(handle()); |
| 163 { | 165 { |
| 164 // Forbid reuse of destroyed nodes as they might be already deallocated. | 166 // Forbid reuse of destroyed nodes as they might be already deallocated. |
| 165 // It's fine though to reuse nodes that were destroyed in weak callback | 167 // It's fine though to reuse nodes that were destroyed in weak callback |
| 166 // as those cannot be deallocated until we are back from the callback. | 168 // as those cannot be deallocated until we are back from the callback. |
| 167 set_first_free(NULL); | 169 GlobalHandles::set_first_free(NULL); |
| 168 if (first_deallocated()) { | 170 if (GlobalHandles::first_deallocated()) { |
| 169 first_deallocated()->set_next(head()); | 171 GlobalHandles::first_deallocated()->set_next(GlobalHandles::head()); |
| 170 } | 172 } |
| 171 // Leaving V8. | 173 // Leaving V8. |
| 172 VMState state(EXTERNAL); | 174 VMState state(EXTERNAL); |
| 173 func(object, par); | 175 func(object, par); |
| 174 } | 176 } |
| 175 return true; | 177 return true; |
| 176 } | 178 } |
| 177 | 179 |
| 178 // Place the handle address first to avoid offset computation. | 180 // Place the handle address first to avoid offset computation. |
| 179 Object* object_; // Storage for object pointer. | 181 Object* object_; // Storage for object pointer. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 next_ = new_nodes + 1; | 253 next_ = new_nodes + 1; |
| 252 limit_ = new_nodes + kNodesPerChunk; | 254 limit_ = new_nodes + kNodesPerChunk; |
| 253 return new_nodes; | 255 return new_nodes; |
| 254 } | 256 } |
| 255 | 257 |
| 256 Chunk* current_; | 258 Chunk* current_; |
| 257 Node* next_; | 259 Node* next_; |
| 258 Node* limit_; | 260 Node* limit_; |
| 259 }; | 261 }; |
| 260 | 262 |
| 261 | 263 class GlobalHandlesPrivateData { |
| 262 static GlobalHandles::Pool pool_; | 264 public: |
| 263 | 265 GlobalHandles::Pool pool_; |
| 266 }; |
| 264 | 267 |
| 265 Handle<Object> GlobalHandles::Create(Object* value) { | 268 Handle<Object> GlobalHandles::Create(Object* value) { |
| 266 Counters::global_handles.Increment(); | 269 INC_COUNTER(global_handles); |
| 267 Node* result; | 270 Node* result; |
| 268 if (first_free()) { | 271 if (first_free()) { |
| 269 // Take the first node in the free list. | 272 // Take the first node in the free list. |
| 270 result = first_free(); | 273 result = first_free(); |
| 271 set_first_free(result->next_free()); | 274 set_first_free(result->next_free()); |
| 272 } else if (first_deallocated()) { | 275 } else if (first_deallocated()) { |
| 273 // Next try deallocated list | 276 // Next try deallocated list |
| 274 result = first_deallocated(); | 277 result = first_deallocated(); |
| 275 set_first_deallocated(result->next_free()); | 278 set_first_deallocated(result->next_free()); |
| 276 ASSERT(result->next() == head()); | 279 ASSERT(result->next() == head()); |
| 277 set_head(result); | 280 set_head(result); |
| 278 } else { | 281 } else { |
| 279 // Allocate a new node. | 282 // Allocate a new node. |
| 280 result = pool_.Allocate(); | 283 result = v8_context()->global_handles_data_.private_data_.pool_.Allocate(); |
| 281 result->set_next(head()); | 284 result->set_next(head()); |
| 282 set_head(result); | 285 set_head(result); |
| 283 } | 286 } |
| 284 result->Initialize(value); | 287 result->Initialize(value); |
| 285 return result->handle(); | 288 return result->handle(); |
| 286 } | 289 } |
| 287 | 290 |
| 288 | 291 |
| 289 void GlobalHandles::Destroy(Object** location) { | 292 void GlobalHandles::Destroy(Object** location) { |
| 290 Counters::global_handles.Decrement(); | 293 DEC_COUNTER(global_handles); |
| 291 if (location == NULL) return; | 294 if (location == NULL) return; |
| 292 Node* node = Node::FromLocation(location); | 295 Node* node = Node::FromLocation(location); |
| 293 node->Destroy(); | 296 node->Destroy(); |
| 294 // Link the destroyed. | 297 // Link the destroyed. |
| 295 node->set_next_free(first_free()); | 298 node->set_next_free(first_free()); |
| 296 set_first_free(node); | 299 set_first_free(node); |
| 297 } | 300 } |
| 298 | 301 |
| 299 | 302 |
| 300 void GlobalHandles::MakeWeak(Object** location, void* parameter, | 303 void GlobalHandles::MakeWeak(Object** location, void* parameter, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 315 | 318 |
| 316 | 319 |
| 317 bool GlobalHandles::IsWeak(Object** location) { | 320 bool GlobalHandles::IsWeak(Object** location) { |
| 318 return Node::FromLocation(location)->IsWeak(); | 321 return Node::FromLocation(location)->IsWeak(); |
| 319 } | 322 } |
| 320 | 323 |
| 321 | 324 |
| 322 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { | 325 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { |
| 323 // Traversal of GC roots in the global handle list that are marked as | 326 // Traversal of GC roots in the global handle list that are marked as |
| 324 // WEAK or PENDING. | 327 // WEAK or PENDING. |
| 325 for (Node* current = head_; current != NULL; current = current->next()) { | 328 for (Node* current = v8_context()->global_handles_data_.head_; |
| 329 current != NULL; |
| 330 current = current->next()) { |
| 326 if (current->state_ == Node::WEAK | 331 if (current->state_ == Node::WEAK |
| 327 || current->state_ == Node::PENDING | 332 || current->state_ == Node::PENDING |
| 328 || current->state_ == Node::NEAR_DEATH) { | 333 || current->state_ == Node::NEAR_DEATH) { |
| 329 v->VisitPointer(¤t->object_); | 334 v->VisitPointer(¤t->object_); |
| 330 } | 335 } |
| 331 } | 336 } |
| 332 } | 337 } |
| 333 | 338 |
| 334 | 339 |
| 335 void GlobalHandles::IterateWeakRoots(WeakReferenceGuest f, | 340 void GlobalHandles::IterateWeakRoots(WeakReferenceGuest f, |
| 336 WeakReferenceCallback callback) { | 341 WeakReferenceCallback callback) { |
| 337 for (Node* current = head_; current != NULL; current = current->next()) { | 342 for (Node* current = v8_context()->global_handles_data_.head_; |
| 343 current != NULL; |
| 344 current = current->next()) { |
| 338 if (current->IsWeak() && current->callback() == callback) { | 345 if (current->IsWeak() && current->callback() == callback) { |
| 339 f(current->object_, current->parameter()); | 346 f(current->object_, current->parameter()); |
| 340 } | 347 } |
| 341 } | 348 } |
| 342 } | 349 } |
| 343 | 350 |
| 344 | 351 |
| 345 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) { | 352 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) { |
| 346 for (Node* current = head_; current != NULL; current = current->next()) { | 353 for (Node* current = v8_context()->global_handles_data_.head_; |
| 354 current != NULL; |
| 355 current = current->next()) { |
| 347 if (current->state_ == Node::WEAK) { | 356 if (current->state_ == Node::WEAK) { |
| 348 if (f(¤t->object_)) { | 357 if (f(¤t->object_)) { |
| 349 current->state_ = Node::PENDING; | 358 current->state_ = Node::PENDING; |
| 350 LOG(HandleEvent("GlobalHandle::Pending", current->handle().location())); | 359 LOG(HandleEvent("GlobalHandle::Pending", current->handle().location())); |
| 351 } | 360 } |
| 352 } | 361 } |
| 353 } | 362 } |
| 354 } | 363 } |
| 355 | 364 |
| 356 | 365 |
| 357 int post_gc_processing_count = 0; | 366 int post_gc_processing_count = 0; |
| 358 | 367 |
| 359 void GlobalHandles::PostGarbageCollectionProcessing() { | 368 void GlobalHandles::PostGarbageCollectionProcessing() { |
| 360 // Process weak global handle callbacks. This must be done after the | 369 // Process weak global handle callbacks. This must be done after the |
| 361 // GC is completely done, because the callbacks may invoke arbitrary | 370 // GC is completely done, because the callbacks may invoke arbitrary |
| 362 // API functions. | 371 // API functions. |
| 363 // At the same time deallocate all DESTROYED nodes. | 372 // At the same time deallocate all DESTROYED nodes. |
| 364 ASSERT(Heap::gc_state() == Heap::NOT_IN_GC); | 373 ASSERT(Heap::gc_state() == Heap::NOT_IN_GC); |
| 365 const int initial_post_gc_processing_count = ++post_gc_processing_count; | 374 const int initial_post_gc_processing_count = ++post_gc_processing_count; |
| 366 Node** p = &head_; | 375 Node** p = &v8_context()->global_handles_data_.head_; |
| 367 while (*p != NULL) { | 376 while (*p != NULL) { |
| 368 if ((*p)->PostGarbageCollectionProcessing()) { | 377 if ((*p)->PostGarbageCollectionProcessing()) { |
| 369 if (initial_post_gc_processing_count != post_gc_processing_count) { | 378 if (initial_post_gc_processing_count != post_gc_processing_count) { |
| 370 // Weak callback triggered another GC and another round of | 379 // Weak callback triggered another GC and another round of |
| 371 // PostGarbageCollection processing. The current node might | 380 // PostGarbageCollection processing. The current node might |
| 372 // have been deleted in that round, so we need to bail out (or | 381 // have been deleted in that round, so we need to bail out (or |
| 373 // restart the processing). | 382 // restart the processing). |
| 374 break; | 383 break; |
| 375 } | 384 } |
| 376 } | 385 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 389 } | 398 } |
| 390 set_first_free(NULL); | 399 set_first_free(NULL); |
| 391 if (first_deallocated()) { | 400 if (first_deallocated()) { |
| 392 first_deallocated()->set_next(head()); | 401 first_deallocated()->set_next(head()); |
| 393 } | 402 } |
| 394 } | 403 } |
| 395 | 404 |
| 396 | 405 |
| 397 void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) { | 406 void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) { |
| 398 // Traversal of global handles marked as NORMAL. | 407 // Traversal of global handles marked as NORMAL. |
| 399 for (Node* current = head_; current != NULL; current = current->next()) { | 408 for (Node* current = v8_context()->global_handles_data_.head_; |
| 409 current != NULL; |
| 410 current = current->next()) { |
| 400 if (current->state_ == Node::NORMAL) { | 411 if (current->state_ == Node::NORMAL) { |
| 401 v->VisitPointer(¤t->object_); | 412 v->VisitPointer(¤t->object_); |
| 402 } | 413 } |
| 403 } | 414 } |
| 404 } | 415 } |
| 405 | 416 |
| 406 | 417 |
| 407 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) { | 418 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) { |
| 408 for (Node* current = head_; current != NULL; current = current->next()) { | 419 for (Node* current = v8_context()->global_handles_data_.head_; |
| 420 current != NULL; |
| 421 current = current->next()) { |
| 409 if (current->state_ != Node::DESTROYED) { | 422 if (current->state_ != Node::DESTROYED) { |
| 410 v->VisitPointer(¤t->object_); | 423 v->VisitPointer(¤t->object_); |
| 411 } | 424 } |
| 412 } | 425 } |
| 413 } | 426 } |
| 414 | 427 |
| 415 | 428 |
| 416 void GlobalHandles::TearDown() { | 429 void GlobalHandles::TearDown() { |
| 417 // Reset all the lists. | 430 // Reset all the lists. |
| 418 set_head(NULL); | 431 set_head(NULL); |
| 419 set_first_free(NULL); | 432 set_first_free(NULL); |
| 420 set_first_deallocated(NULL); | 433 set_first_deallocated(NULL); |
| 421 pool_.Release(); | 434 v8_context()->global_handles_data_.private_data_.pool_.Release(); |
| 422 } | 435 } |
| 423 | 436 |
| 437 GlobalHandlesData::GlobalHandlesData() |
| 438 :number_of_weak_handles_(0), |
| 439 number_of_global_object_weak_handles_(0), |
| 440 head_(NULL), |
| 441 first_free_(NULL), |
| 442 private_data_(*new GlobalHandlesPrivateData()), |
| 443 first_deallocated_(NULL) { |
| 444 } |
| 424 | 445 |
| 425 int GlobalHandles::number_of_weak_handles_ = 0; | 446 GlobalHandlesData::~GlobalHandlesData() { |
| 426 int GlobalHandles::number_of_global_object_weak_handles_ = 0; | 447 delete &private_data_; |
| 427 | 448 } |
| 428 GlobalHandles::Node* GlobalHandles::head_ = NULL; | |
| 429 GlobalHandles::Node* GlobalHandles::first_free_ = NULL; | |
| 430 GlobalHandles::Node* GlobalHandles::first_deallocated_ = NULL; | |
| 431 | 449 |
| 432 void GlobalHandles::RecordStats(HeapStats* stats) { | 450 void GlobalHandles::RecordStats(HeapStats* stats) { |
| 433 *stats->global_handle_count = 0; | 451 *stats->global_handle_count = 0; |
| 434 *stats->weak_global_handle_count = 0; | 452 *stats->weak_global_handle_count = 0; |
| 435 *stats->pending_global_handle_count = 0; | 453 *stats->pending_global_handle_count = 0; |
| 436 *stats->near_death_global_handle_count = 0; | 454 *stats->near_death_global_handle_count = 0; |
| 437 *stats->destroyed_global_handle_count = 0; | 455 *stats->destroyed_global_handle_count = 0; |
| 438 for (Node* current = head_; current != NULL; current = current->next()) { | 456 for (Node* current = v8_context()->global_handles_data_.head_; |
| 457 current != NULL; current = current->next()) { |
| 439 *stats->global_handle_count += 1; | 458 *stats->global_handle_count += 1; |
| 440 if (current->state_ == Node::WEAK) { | 459 if (current->state_ == Node::WEAK) { |
| 441 *stats->weak_global_handle_count += 1; | 460 *stats->weak_global_handle_count += 1; |
| 442 } else if (current->state_ == Node::PENDING) { | 461 } else if (current->state_ == Node::PENDING) { |
| 443 *stats->pending_global_handle_count += 1; | 462 *stats->pending_global_handle_count += 1; |
| 444 } else if (current->state_ == Node::NEAR_DEATH) { | 463 } else if (current->state_ == Node::NEAR_DEATH) { |
| 445 *stats->near_death_global_handle_count += 1; | 464 *stats->near_death_global_handle_count += 1; |
| 446 } else if (current->state_ == Node::DESTROYED) { | 465 } else if (current->state_ == Node::DESTROYED) { |
| 447 *stats->destroyed_global_handle_count += 1; | 466 *stats->destroyed_global_handle_count += 1; |
| 448 } | 467 } |
| 449 } | 468 } |
| 450 } | 469 } |
| 451 | 470 |
| 452 #ifdef DEBUG | 471 #ifdef DEBUG |
| 453 | 472 |
| 454 void GlobalHandles::PrintStats() { | 473 void GlobalHandles::PrintStats() { |
| 455 int total = 0; | 474 int total = 0; |
| 456 int weak = 0; | 475 int weak = 0; |
| 457 int pending = 0; | 476 int pending = 0; |
| 458 int near_death = 0; | 477 int near_death = 0; |
| 459 int destroyed = 0; | 478 int destroyed = 0; |
| 460 | 479 |
| 461 for (Node* current = head_; current != NULL; current = current->next()) { | 480 for (Node* current = v8_context()->global_handles_data_.head_; |
| 481 current != NULL; |
| 482 current = current->next()) { |
| 462 total++; | 483 total++; |
| 463 if (current->state_ == Node::WEAK) weak++; | 484 if (current->state_ == Node::WEAK) weak++; |
| 464 if (current->state_ == Node::PENDING) pending++; | 485 if (current->state_ == Node::PENDING) pending++; |
| 465 if (current->state_ == Node::NEAR_DEATH) near_death++; | 486 if (current->state_ == Node::NEAR_DEATH) near_death++; |
| 466 if (current->state_ == Node::DESTROYED) destroyed++; | 487 if (current->state_ == Node::DESTROYED) destroyed++; |
| 467 } | 488 } |
| 468 | 489 |
| 469 PrintF("Global Handle Statistics:\n"); | 490 PrintF("Global Handle Statistics:\n"); |
| 470 PrintF(" allocated memory = %dB\n", sizeof(Node) * total); | 491 PrintF(" allocated memory = %dB\n", sizeof(Node) * total); |
| 471 PrintF(" # weak = %d\n", weak); | 492 PrintF(" # weak = %d\n", weak); |
| 472 PrintF(" # pending = %d\n", pending); | 493 PrintF(" # pending = %d\n", pending); |
| 473 PrintF(" # near_death = %d\n", near_death); | 494 PrintF(" # near_death = %d\n", near_death); |
| 474 PrintF(" # destroyed = %d\n", destroyed); | 495 PrintF(" # destroyed = %d\n", destroyed); |
| 475 PrintF(" # total = %d\n", total); | 496 PrintF(" # total = %d\n", total); |
| 476 } | 497 } |
| 477 | 498 |
| 478 void GlobalHandles::Print() { | 499 void GlobalHandles::Print() { |
| 479 PrintF("Global handles:\n"); | 500 PrintF("Global handles:\n"); |
| 480 for (Node* current = head_; current != NULL; current = current->next()) { | 501 for (Node* current = v8_context()->global_handles_data_.head_; |
| 502 current != NULL; |
| 503 current = current->next()) { |
| 481 PrintF(" handle %p to %p (weak=%d)\n", current->handle().location(), | 504 PrintF(" handle %p to %p (weak=%d)\n", current->handle().location(), |
| 482 *current->handle(), current->state_ == Node::WEAK); | 505 *current->handle(), current->state_ == Node::WEAK); |
| 483 } | 506 } |
| 484 } | 507 } |
| 485 | 508 |
| 486 #endif | 509 #endif |
| 487 | 510 |
| 488 List<ObjectGroup*>* GlobalHandles::ObjectGroups() { | 511 List<ObjectGroup*>* GlobalHandles::ObjectGroups() { |
| 489 // Lazily initialize the list to avoid startup time static constructors. | 512 // Lazily initialize the list to avoid startup time static constructors. |
| 490 static List<ObjectGroup*> groups(4); | 513 static List<ObjectGroup*> groups(4); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 502 void GlobalHandles::RemoveObjectGroups() { | 525 void GlobalHandles::RemoveObjectGroups() { |
| 503 List<ObjectGroup*>* object_groups = ObjectGroups(); | 526 List<ObjectGroup*>* object_groups = ObjectGroups(); |
| 504 for (int i = 0; i< object_groups->length(); i++) { | 527 for (int i = 0; i< object_groups->length(); i++) { |
| 505 delete object_groups->at(i); | 528 delete object_groups->at(i); |
| 506 } | 529 } |
| 507 object_groups->Clear(); | 530 object_groups->Clear(); |
| 508 } | 531 } |
| 509 | 532 |
| 510 | 533 |
| 511 } } // namespace v8::internal | 534 } } // namespace v8::internal |
| OLD | NEW |