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

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

Issue 7043003: Version 3.3.8 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 7 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 | « src/global-handles.h ('k') | src/handles.h » ('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 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 30 matching lines...) Expand all
41 } 41 }
42 42
43 43
44 class GlobalHandles::Node : public Malloced { 44 class GlobalHandles::Node : public Malloced {
45 public: 45 public:
46 46
47 void Initialize(Object* object) { 47 void Initialize(Object* object) {
48 // Set the initial value of the handle. 48 // Set the initial value of the handle.
49 object_ = object; 49 object_ = object;
50 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 50 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
51 independent_ = false;
51 state_ = NORMAL; 52 state_ = NORMAL;
52 parameter_or_next_free_.parameter = NULL; 53 parameter_or_next_free_.parameter = NULL;
53 callback_ = NULL; 54 callback_ = NULL;
54 } 55 }
55 56
56 Node() { 57 Node() {
57 state_ = DESTROYED; 58 state_ = DESTROYED;
58 } 59 }
59 60
60 explicit Node(Object* object) { 61 explicit Node(Object* object) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 if (state_ == WEAK || IsNearDeath()) { 132 if (state_ == WEAK || IsNearDeath()) {
132 global_handles->number_of_weak_handles_--; 133 global_handles->number_of_weak_handles_--;
133 if (object_->IsJSGlobalObject()) { 134 if (object_->IsJSGlobalObject()) {
134 global_handles->number_of_global_object_weak_handles_--; 135 global_handles->number_of_global_object_weak_handles_--;
135 } 136 }
136 } 137 }
137 state_ = NORMAL; 138 state_ = NORMAL;
138 set_parameter(NULL); 139 set_parameter(NULL);
139 } 140 }
140 141
142 void MarkIndependent(GlobalHandles* global_handles) {
143 LOG(global_handles->isolate(),
144 HandleEvent("GlobalHandle::MarkIndependent", handle().location()));
145 ASSERT(state_ != DESTROYED);
146 independent_ = true;
147 }
148
141 bool IsNearDeath() { 149 bool IsNearDeath() {
142 // Check for PENDING to ensure correct answer when processing callbacks. 150 // Check for PENDING to ensure correct answer when processing callbacks.
143 return state_ == PENDING || state_ == NEAR_DEATH; 151 return state_ == PENDING || state_ == NEAR_DEATH;
144 } 152 }
145 153
146 bool IsWeak() { 154 bool IsWeak() {
147 return state_ == WEAK; 155 return state_ == WEAK;
148 } 156 }
149 157
150 bool CanBeRetainer() { 158 bool CanBeRetainer() {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 // NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, DESTROYED } 223 // NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, DESTROYED }
216 enum State { 224 enum State {
217 NORMAL, // Normal global handle. 225 NORMAL, // Normal global handle.
218 WEAK, // Flagged as weak but not yet finalized. 226 WEAK, // Flagged as weak but not yet finalized.
219 PENDING, // Has been recognized as only reachable by weak handles. 227 PENDING, // Has been recognized as only reachable by weak handles.
220 NEAR_DEATH, // Callback has informed the handle is near death. 228 NEAR_DEATH, // Callback has informed the handle is near death.
221 DESTROYED 229 DESTROYED
222 }; 230 };
223 State state_ : 4; // Need one more bit for MSVC as it treats enums as signed. 231 State state_ : 4; // Need one more bit for MSVC as it treats enums as signed.
224 232
233 bool independent_ : 1;
234
225 private: 235 private:
226 // Handle specific callback. 236 // Handle specific callback.
227 WeakReferenceCallback callback_; 237 WeakReferenceCallback callback_;
228 // Provided data for callback. In DESTROYED state, this is used for 238 // Provided data for callback. In DESTROYED state, this is used for
229 // the free list link. 239 // the free list link.
230 union { 240 union {
231 void* parameter; 241 void* parameter;
232 Node* next_free; 242 Node* next_free;
233 } parameter_or_next_free_; 243 } parameter_or_next_free_;
234 244
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 ASSERT(callback != NULL); 367 ASSERT(callback != NULL);
358 Node::FromLocation(location)->MakeWeak(this, parameter, callback); 368 Node::FromLocation(location)->MakeWeak(this, parameter, callback);
359 } 369 }
360 370
361 371
362 void GlobalHandles::ClearWeakness(Object** location) { 372 void GlobalHandles::ClearWeakness(Object** location) {
363 Node::FromLocation(location)->ClearWeakness(this); 373 Node::FromLocation(location)->ClearWeakness(this);
364 } 374 }
365 375
366 376
377 void GlobalHandles::MarkIndependent(Object** location) {
378 Node::FromLocation(location)->MarkIndependent(this);
379 }
380
381
367 bool GlobalHandles::IsNearDeath(Object** location) { 382 bool GlobalHandles::IsNearDeath(Object** location) {
368 return Node::FromLocation(location)->IsNearDeath(); 383 return Node::FromLocation(location)->IsNearDeath();
369 } 384 }
370 385
371 386
372 bool GlobalHandles::IsWeak(Object** location) { 387 bool GlobalHandles::IsWeak(Object** location) {
373 return Node::FromLocation(location)->IsWeak(); 388 return Node::FromLocation(location)->IsWeak();
374 } 389 }
375 390
376 391
377 void GlobalHandles::SetWrapperClassId(Object** location, uint16_t class_id) { 392 void GlobalHandles::SetWrapperClassId(Object** location, uint16_t class_id) {
378 Node::FromLocation(location)->SetWrapperClassId(class_id); 393 Node::FromLocation(location)->SetWrapperClassId(class_id);
379 } 394 }
380 395
381 396
382 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { 397 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
383 // Traversal of GC roots in the global handle list that are marked as 398 // Traversal of GC roots in the global handle list that are marked as
384 // WEAK or PENDING. 399 // WEAK, PENDING or NEAR_DEATH.
385 for (Node* current = head_; current != NULL; current = current->next()) { 400 for (Node* current = head_; current != NULL; current = current->next()) {
386 if (current->state_ == Node::WEAK 401 if (current->state_ == Node::WEAK
387 || current->state_ == Node::PENDING 402 || current->state_ == Node::PENDING
388 || current->state_ == Node::NEAR_DEATH) { 403 || current->state_ == Node::NEAR_DEATH) {
389 v->VisitPointer(&current->object_); 404 v->VisitPointer(&current->object_);
390 } 405 }
391 } 406 }
392 } 407 }
393 408
394 409
410 void GlobalHandles::IterateWeakIndependentRoots(ObjectVisitor* v) {
411 // Traversal of GC roots in the global handle list that are independent
412 // and marked as WEAK, PENDING or NEAR_DEATH.
413 for (Node* current = head_; current != NULL; current = current->next()) {
414 if (!current->independent_) continue;
415 if (current->state_ == Node::WEAK
416 || current->state_ == Node::PENDING
417 || current->state_ == Node::NEAR_DEATH) {
418 v->VisitPointer(&current->object_);
419 }
420 }
421 }
422
423
395 void GlobalHandles::IterateWeakRoots(WeakReferenceGuest f, 424 void GlobalHandles::IterateWeakRoots(WeakReferenceGuest f,
396 WeakReferenceCallback callback) { 425 WeakReferenceCallback callback) {
397 for (Node* current = head_; current != NULL; current = current->next()) { 426 for (Node* current = head_; current != NULL; current = current->next()) {
398 if (current->IsWeak() && current->callback() == callback) { 427 if (current->IsWeak() && current->callback() == callback) {
399 f(current->object_, current->parameter()); 428 f(current->object_, current->parameter());
400 } 429 }
401 } 430 }
402 } 431 }
403 432
404 433
405 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) { 434 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
406 for (Node* current = head_; current != NULL; current = current->next()) { 435 for (Node* current = head_; current != NULL; current = current->next()) {
407 if (current->state_ == Node::WEAK) { 436 if (current->state_ == Node::WEAK) {
408 if (f(&current->object_)) { 437 if (f(&current->object_)) {
409 current->state_ = Node::PENDING; 438 current->state_ = Node::PENDING;
410 LOG(isolate_, 439 LOG(isolate_,
411 HandleEvent("GlobalHandle::Pending", current->handle().location())); 440 HandleEvent("GlobalHandle::Pending", current->handle().location()));
412 } 441 }
413 } 442 }
414 } 443 }
415 } 444 }
416 445
417 446
418 bool GlobalHandles::PostGarbageCollectionProcessing() { 447 void GlobalHandles::IdentifyWeakIndependentHandles(WeakSlotCallbackWithHeap f) {
448 for (Node* current = head_; current != NULL; current = current->next()) {
449 if (current->state_ == Node::WEAK && current->independent_) {
450 if (f(isolate_->heap(), &current->object_)) {
451 current->state_ = Node::PENDING;
452 LOG(isolate_,
453 HandleEvent("GlobalHandle::Pending", current->handle().location()));
454 }
455 }
456 }
457 }
458
459
460 bool GlobalHandles::PostGarbageCollectionProcessing(
461 GarbageCollector collector) {
419 // Process weak global handle callbacks. This must be done after the 462 // Process weak global handle callbacks. This must be done after the
420 // GC is completely done, because the callbacks may invoke arbitrary 463 // GC is completely done, because the callbacks may invoke arbitrary
421 // API functions. 464 // API functions.
422 // At the same time deallocate all DESTROYED nodes. 465 // At the same time deallocate all DESTROYED nodes.
423 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 466 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
424 const int initial_post_gc_processing_count = ++post_gc_processing_count_; 467 const int initial_post_gc_processing_count = ++post_gc_processing_count_;
425 bool next_gc_likely_to_collect_more = false; 468 bool next_gc_likely_to_collect_more = false;
426 Node** p = &head_; 469 Node** p = &head_;
427 while (*p != NULL) { 470 while (*p != NULL) {
471 // Skip dependent handles. Their weak callbacks might expect to be
472 // called between two global garbage collection callbacks which
473 // are not called for minor collections.
474 if (collector == SCAVENGER && !(*p)->independent_) {
475 p = (*p)->next_addr();
476 continue;
477 }
478
428 if ((*p)->PostGarbageCollectionProcessing(isolate_, this)) { 479 if ((*p)->PostGarbageCollectionProcessing(isolate_, this)) {
429 if (initial_post_gc_processing_count != post_gc_processing_count_) { 480 if (initial_post_gc_processing_count != post_gc_processing_count_) {
430 // Weak callback triggered another GC and another round of 481 // Weak callback triggered another GC and another round of
431 // PostGarbageCollection processing. The current node might 482 // PostGarbageCollection processing. The current node might
432 // have been deleted in that round, so we need to bail out (or 483 // have been deleted in that round, so we need to bail out (or
433 // restart the processing). 484 // restart the processing).
434 break; 485 break;
435 } 486 }
436 } 487 }
437 if ((*p)->state_ == Node::DESTROYED) { 488 if ((*p)->state_ == Node::DESTROYED) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 520
470 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) { 521 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) {
471 for (Node* current = head_; current != NULL; current = current->next()) { 522 for (Node* current = head_; current != NULL; current = current->next()) {
472 if (current->state_ != Node::DESTROYED) { 523 if (current->state_ != Node::DESTROYED) {
473 v->VisitPointer(&current->object_); 524 v->VisitPointer(&current->object_);
474 } 525 }
475 } 526 }
476 } 527 }
477 528
478 529
530 void GlobalHandles::IterateStrongAndDependentRoots(ObjectVisitor* v) {
531 for (Node* current = head_; current != NULL; current = current->next()) {
532 if ((current->independent_ && current->state_ == Node::NORMAL) ||
533 (!current->independent_ && current->state_ != Node::DESTROYED)) {
534 v->VisitPointer(&current->object_);
535 }
536 }
537 }
538
539
479 void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) { 540 void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) {
480 for (Node* current = head_; current != NULL; current = current->next()) { 541 for (Node* current = head_; current != NULL; current = current->next()) {
481 if (current->class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId && 542 if (current->class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId &&
482 current->CanBeRetainer()) { 543 current->CanBeRetainer()) {
483 v->VisitEmbedderReference(&current->object_, current->class_id_); 544 v->VisitEmbedderReference(&current->object_, current->class_id_);
484 } 545 }
485 } 546 }
486 } 547 }
487 548
488 549
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 645
585 void GlobalHandles::RemoveImplicitRefGroups() { 646 void GlobalHandles::RemoveImplicitRefGroups() {
586 for (int i = 0; i < implicit_ref_groups_.length(); i++) { 647 for (int i = 0; i < implicit_ref_groups_.length(); i++) {
587 implicit_ref_groups_.at(i)->Dispose(); 648 implicit_ref_groups_.at(i)->Dispose();
588 } 649 }
589 implicit_ref_groups_.Clear(); 650 implicit_ref_groups_.Clear();
590 } 651 }
591 652
592 653
593 } } // namespace v8::internal 654 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/global-handles.h ('k') | src/handles.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698