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

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

Issue 7031005: Extend Handle API with MarkIndependent. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
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
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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 object_groups_(4) { 320 object_groups_(4) {
311 } 321 }
312 322
313 323
314 GlobalHandles::~GlobalHandles() { 324 GlobalHandles::~GlobalHandles() {
315 delete pool_; 325 delete pool_;
316 pool_ = 0; 326 pool_ = 0;
317 } 327 }
318 328
319 329
320 Handle<Object> GlobalHandles::Create(Object* value) { 330 Handle<Object> GlobalHandles::Create(Object* value) {
antonm 2011/05/16 14:13:19 I think you should reset independent flag here.
Vyacheslav Egorov (Chromium) 2011/05/16 14:55:34 It's done by result->Initialize(value) below. Am I
antonm 2011/05/16 15:20:44 Sorry, missed this one. On 2011/05/16 14:55:34, V
321 isolate_->counters()->global_handles()->Increment(); 331 isolate_->counters()->global_handles()->Increment();
322 Node* result; 332 Node* result;
323 if (first_free()) { 333 if (first_free()) {
324 // Take the first node in the free list. 334 // Take the first node in the free list.
325 result = first_free(); 335 result = first_free();
326 set_first_free(result->next_free()); 336 set_first_free(result->next_free());
327 } else if (first_deallocated()) { 337 } else if (first_deallocated()) {
328 // Next try deallocated list 338 // Next try deallocated list
329 result = first_deallocated(); 339 result = first_deallocated();
330 set_first_deallocated(result->next_free()); 340 set_first_deallocated(result->next_free());
(...skipping 26 matching lines...) Expand all
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 or PENDING.
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 marked as
412 // WEAK or PENDING.
antonm 2011/05/16 14:13:19 comment is wrong.
Vyacheslav Egorov (Chromium) 2011/05/16 14:55:34 Thanks! Will fix.
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
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
418 bool GlobalHandles::PostGarbageCollectionProcessing() { 460 bool GlobalHandles::PostGarbageCollectionProcessing() {
419 // Process weak global handle callbacks. This must be done after the 461 // Process weak global handle callbacks. This must be done after the
420 // GC is completely done, because the callbacks may invoke arbitrary 462 // GC is completely done, because the callbacks may invoke arbitrary
421 // API functions. 463 // API functions.
422 // At the same time deallocate all DESTROYED nodes. 464 // At the same time deallocate all DESTROYED nodes.
423 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 465 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
424 const int initial_post_gc_processing_count = ++post_gc_processing_count_; 466 const int initial_post_gc_processing_count = ++post_gc_processing_count_;
425 bool next_gc_likely_to_collect_more = false; 467 bool next_gc_likely_to_collect_more = false;
426 Node** p = &head_; 468 Node** p = &head_;
427 while (*p != NULL) { 469 while (*p != NULL) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 511
470 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) { 512 void GlobalHandles::IterateAllRoots(ObjectVisitor* v) {
471 for (Node* current = head_; current != NULL; current = current->next()) { 513 for (Node* current = head_; current != NULL; current = current->next()) {
472 if (current->state_ != Node::DESTROYED) { 514 if (current->state_ != Node::DESTROYED) {
473 v->VisitPointer(&current->object_); 515 v->VisitPointer(&current->object_);
474 } 516 }
475 } 517 }
476 } 518 }
477 519
478 520
521 void GlobalHandles::IterateStrongAndDependentRoots(ObjectVisitor* v) {
522 for (Node* current = head_; current != NULL; current = current->next()) {
523 if ((current->independent_ && current->state_ == Node::NORMAL) ||
524 (!current->independent_ && current->state_ != Node::DESTROYED)) {
525 v->VisitPointer(&current->object_);
526 }
527 }
528 }
529
530
479 void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) { 531 void GlobalHandles::IterateAllRootsWithClassIds(ObjectVisitor* v) {
480 for (Node* current = head_; current != NULL; current = current->next()) { 532 for (Node* current = head_; current != NULL; current = current->next()) {
481 if (current->class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId && 533 if (current->class_id_ != v8::HeapProfiler::kPersistentHandleNoClassId &&
482 current->CanBeRetainer()) { 534 current->CanBeRetainer()) {
483 v->VisitEmbedderReference(&current->object_, current->class_id_); 535 v->VisitEmbedderReference(&current->object_, current->class_id_);
484 } 536 }
485 } 537 }
486 } 538 }
487 539
488 540
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 636
585 void GlobalHandles::RemoveImplicitRefGroups() { 637 void GlobalHandles::RemoveImplicitRefGroups() {
586 for (int i = 0; i < implicit_ref_groups_.length(); i++) { 638 for (int i = 0; i < implicit_ref_groups_.length(); i++) {
587 implicit_ref_groups_.at(i)->Dispose(); 639 implicit_ref_groups_.at(i)->Dispose();
588 } 640 }
589 implicit_ref_groups_.Clear(); 641 implicit_ref_groups_.Clear();
590 } 642 }
591 643
592 644
593 } } // namespace v8::internal 645 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698