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

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

Issue 1950963002: Introduce a new phantom weakness type without finalization callback. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: comment Created 4 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
« no previous file with comments | « src/global-handles.h ('k') | test/cctest/test-global-handles.cc » ('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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/global-handles.h" 5 #include "src/global-handles.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/v8.h" 8 #include "src/v8.h"
9 #include "src/vm-state-inl.h" 9 #include "src/vm-state-inl.h"
10 10
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 187
188 bool IsNearDeath() const { 188 bool IsNearDeath() const {
189 // Check for PENDING to ensure correct answer when processing callbacks. 189 // Check for PENDING to ensure correct answer when processing callbacks.
190 return state() == PENDING || state() == NEAR_DEATH; 190 return state() == PENDING || state() == NEAR_DEATH;
191 } 191 }
192 192
193 bool IsWeak() const { return state() == WEAK; } 193 bool IsWeak() const { return state() == WEAK; }
194 194
195 bool IsInUse() const { return state() != FREE; } 195 bool IsInUse() const { return state() != FREE; }
196 196
197 bool IsPendingPhantomCallback() const {
198 return state() == PENDING &&
199 (weakness_type() == PHANTOM_WEAK ||
200 weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS);
201 }
202
203 bool IsPendingPhantomResetHandle() const {
204 return state() == PENDING && weakness_type() == PHANTOM_WEAK_RESET_HANDLE;
205 }
206
197 bool IsRetainer() const { 207 bool IsRetainer() const {
198 return state() != FREE && 208 return state() != FREE &&
199 !(state() == NEAR_DEATH && weakness_type() != FINALIZER_WEAK); 209 !(state() == NEAR_DEATH && weakness_type() != FINALIZER_WEAK);
200 } 210 }
201 211
202 bool IsStrongRetainer() const { return state() == NORMAL; } 212 bool IsStrongRetainer() const { return state() == NORMAL; }
203 213
204 bool IsWeakRetainer() const { 214 bool IsWeakRetainer() const {
205 return state() == WEAK || state() == PENDING || 215 return state() == WEAK || state() == PENDING ||
206 (state() == NEAR_DEATH && weakness_type() == FINALIZER_WEAK); 216 (state() == NEAR_DEATH && weakness_type() == FINALIZER_WEAK);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 set_weakness_type(PHANTOM_WEAK_2_INTERNAL_FIELDS); 274 set_weakness_type(PHANTOM_WEAK_2_INTERNAL_FIELDS);
265 break; 275 break;
266 case v8::WeakCallbackType::kFinalizer: 276 case v8::WeakCallbackType::kFinalizer:
267 set_weakness_type(FINALIZER_WEAK); 277 set_weakness_type(FINALIZER_WEAK);
268 break; 278 break;
269 } 279 }
270 set_parameter(parameter); 280 set_parameter(parameter);
271 weak_callback_ = phantom_callback; 281 weak_callback_ = phantom_callback;
272 } 282 }
273 283
284 void MakeWeak(Object*** location_addr) {
285 DCHECK(IsInUse());
286 CHECK_NE(object_, reinterpret_cast<Object*>(kGlobalHandleZapValue));
287 set_state(WEAK);
288 set_weakness_type(PHANTOM_WEAK_RESET_HANDLE);
289 set_parameter(location_addr);
290 weak_callback_ = nullptr;
291 }
292
274 void* ClearWeakness() { 293 void* ClearWeakness() {
275 DCHECK(IsInUse()); 294 DCHECK(IsInUse());
276 void* p = parameter(); 295 void* p = parameter();
277 set_state(NORMAL); 296 set_state(NORMAL);
278 set_parameter(NULL); 297 set_parameter(NULL);
279 return p; 298 return p;
280 } 299 }
281 300
282 void CollectPhantomCallbackData( 301 void CollectPhantomCallbackData(
283 Isolate* isolate, 302 Isolate* isolate,
284 List<PendingPhantomCallback>* pending_phantom_callbacks) { 303 List<PendingPhantomCallback>* pending_phantom_callbacks) {
285 DCHECK(weakness_type() == PHANTOM_WEAK || 304 DCHECK(weakness_type() == PHANTOM_WEAK ||
286 weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); 305 weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS);
287 DCHECK(state() == PENDING); 306 DCHECK(state() == PENDING);
307 DCHECK(weak_callback_ != nullptr);
288 308
289 void* internal_fields[v8::kInternalFieldsInWeakCallback] = {nullptr, 309 void* internal_fields[v8::kInternalFieldsInWeakCallback] = {nullptr,
290 nullptr}; 310 nullptr};
291 if (weakness_type() != PHANTOM_WEAK && object()->IsJSObject()) { 311 if (weakness_type() != PHANTOM_WEAK && object()->IsJSObject()) {
292 auto jsobject = JSObject::cast(object()); 312 auto jsobject = JSObject::cast(object());
293 int field_count = jsobject->GetInternalFieldCount(); 313 int field_count = jsobject->GetInternalFieldCount();
294 for (int i = 0; i < v8::kInternalFieldsInWeakCallback; ++i) { 314 for (int i = 0; i < v8::kInternalFieldsInWeakCallback; ++i) {
295 if (field_count == i) break; 315 if (field_count == i) break;
296 auto field = jsobject->GetInternalField(i); 316 auto field = jsobject->GetInternalField(i);
297 if (field->IsSmi()) internal_fields[i] = field; 317 if (field->IsSmi()) internal_fields[i] = field;
298 } 318 }
299 } 319 }
300 320
301 // Zap with something dangerous. 321 // Zap with something dangerous.
302 *location() = reinterpret_cast<Object*>(0x6057ca11); 322 *location() = reinterpret_cast<Object*>(0x6057ca11);
303 323
304 typedef v8::WeakCallbackInfo<void> Data; 324 typedef v8::WeakCallbackInfo<void> Data;
305 auto callback = reinterpret_cast<Data::Callback>(weak_callback_); 325 auto callback = reinterpret_cast<Data::Callback>(weak_callback_);
306 pending_phantom_callbacks->Add( 326 pending_phantom_callbacks->Add(
307 PendingPhantomCallback(this, callback, parameter(), internal_fields)); 327 PendingPhantomCallback(this, callback, parameter(), internal_fields));
308 DCHECK(IsInUse()); 328 DCHECK(IsInUse());
309 set_state(NEAR_DEATH); 329 set_state(NEAR_DEATH);
310 } 330 }
311 331
332 void ResetPhantomHandle() {
333 DCHECK(weakness_type() == PHANTOM_WEAK_RESET_HANDLE);
334 DCHECK(state() == PENDING);
335 DCHECK(weak_callback_ == nullptr);
336 Object*** handle = reinterpret_cast<Object***>(parameter());
337 *handle = nullptr;
338 Release();
339 }
340
312 bool PostGarbageCollectionProcessing(Isolate* isolate) { 341 bool PostGarbageCollectionProcessing(Isolate* isolate) {
313 // Handles only weak handles (not phantom) that are dying. 342 // Handles only weak handles (not phantom) that are dying.
314 if (state() != Node::PENDING) return false; 343 if (state() != Node::PENDING) return false;
315 if (weak_callback_ == NULL) { 344 if (weak_callback_ == NULL) {
316 Release(); 345 Release();
317 return false; 346 return false;
318 } 347 }
319 set_state(NEAR_DEATH); 348 set_state(NEAR_DEATH);
320 349
321 // Check that we are not passing a finalized external string to 350 // Check that we are not passing a finalized external string to
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 isolate()->heap()->CallGCEpilogueCallbacks( 562 isolate()->heap()->CallGCEpilogueCallbacks(
534 GCType::kGCTypeProcessWeakCallbacks, kNoGCCallbackFlags); 563 GCType::kGCTypeProcessWeakCallbacks, kNoGCCallbackFlags);
535 } 564 }
536 565
537 private: 566 private:
538 List<PendingPhantomCallback> pending_phantom_callbacks_; 567 List<PendingPhantomCallback> pending_phantom_callbacks_;
539 568
540 DISALLOW_COPY_AND_ASSIGN(PendingPhantomCallbacksSecondPassTask); 569 DISALLOW_COPY_AND_ASSIGN(PendingPhantomCallbacksSecondPassTask);
541 }; 570 };
542 571
543
544 GlobalHandles::GlobalHandles(Isolate* isolate) 572 GlobalHandles::GlobalHandles(Isolate* isolate)
545 : isolate_(isolate), 573 : isolate_(isolate),
546 number_of_global_handles_(0), 574 number_of_global_handles_(0),
547 first_block_(NULL), 575 first_block_(NULL),
548 first_used_block_(NULL), 576 first_used_block_(NULL),
549 first_free_(NULL), 577 first_free_(NULL),
550 post_gc_processing_count_(0), 578 post_gc_processing_count_(0),
579 number_of_phantom_handle_resets_(0),
551 object_group_connections_(kObjectGroupConnectionsCapacity) {} 580 object_group_connections_(kObjectGroupConnectionsCapacity) {}
552 581
553
554 GlobalHandles::~GlobalHandles() { 582 GlobalHandles::~GlobalHandles() {
555 NodeBlock* block = first_block_; 583 NodeBlock* block = first_block_;
556 while (block != NULL) { 584 while (block != NULL) {
557 NodeBlock* tmp = block->next(); 585 NodeBlock* tmp = block->next();
558 delete block; 586 delete block;
559 block = tmp; 587 block = tmp;
560 } 588 }
561 first_block_ = NULL; 589 first_block_ = NULL;
562 } 590 }
563 591
(...skipping 30 matching lines...) Expand all
594 622
595 typedef v8::WeakCallbackInfo<void>::Callback GenericCallback; 623 typedef v8::WeakCallbackInfo<void>::Callback GenericCallback;
596 624
597 625
598 void GlobalHandles::MakeWeak(Object** location, void* parameter, 626 void GlobalHandles::MakeWeak(Object** location, void* parameter,
599 GenericCallback phantom_callback, 627 GenericCallback phantom_callback,
600 v8::WeakCallbackType type) { 628 v8::WeakCallbackType type) {
601 Node::FromLocation(location)->MakeWeak(parameter, phantom_callback, type); 629 Node::FromLocation(location)->MakeWeak(parameter, phantom_callback, type);
602 } 630 }
603 631
632 void GlobalHandles::MakeWeak(Object*** location_addr) {
633 Node::FromLocation(*location_addr)->MakeWeak(location_addr);
634 }
604 635
605 void* GlobalHandles::ClearWeakness(Object** location) { 636 void* GlobalHandles::ClearWeakness(Object** location) {
606 return Node::FromLocation(location)->ClearWeakness(); 637 return Node::FromLocation(location)->ClearWeakness();
607 } 638 }
608 639
609 640
610 void GlobalHandles::MarkIndependent(Object** location) { 641 void GlobalHandles::MarkIndependent(Object** location) {
611 Node::FromLocation(location)->MarkIndependent(); 642 Node::FromLocation(location)->MarkIndependent();
612 } 643 }
613 644
(...skipping 15 matching lines...) Expand all
629 660
630 bool GlobalHandles::IsWeak(Object** location) { 661 bool GlobalHandles::IsWeak(Object** location) {
631 return Node::FromLocation(location)->IsWeak(); 662 return Node::FromLocation(location)->IsWeak();
632 } 663 }
633 664
634 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { 665 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
635 for (NodeIterator it(this); !it.done(); it.Advance()) { 666 for (NodeIterator it(this); !it.done(); it.Advance()) {
636 Node* node = it.node(); 667 Node* node = it.node();
637 if (node->IsWeakRetainer()) { 668 if (node->IsWeakRetainer()) {
638 // Pending weak phantom handles die immediately. Everything else survives. 669 // Pending weak phantom handles die immediately. Everything else survives.
639 if (node->state() == Node::PENDING && 670 if (node->IsPendingPhantomResetHandle()) {
640 node->weakness_type() != FINALIZER_WEAK) { 671 node->ResetPhantomHandle();
672 ++number_of_phantom_handle_resets_;
673 } else if (node->IsPendingPhantomCallback()) {
641 node->CollectPhantomCallbackData(isolate(), 674 node->CollectPhantomCallbackData(isolate(),
642 &pending_phantom_callbacks_); 675 &pending_phantom_callbacks_);
643 } else { 676 } else {
644 v->VisitPointer(node->location()); 677 v->VisitPointer(node->location());
645 } 678 }
646 } 679 }
647 } 680 }
648 } 681 }
649 682
650 683
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 } 723 }
691 724
692 725
693 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { 726 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
694 for (int i = 0; i < new_space_nodes_.length(); ++i) { 727 for (int i = 0; i < new_space_nodes_.length(); ++i) {
695 Node* node = new_space_nodes_[i]; 728 Node* node = new_space_nodes_[i];
696 DCHECK(node->is_in_new_space_list()); 729 DCHECK(node->is_in_new_space_list());
697 if ((node->is_independent() || node->is_partially_dependent()) && 730 if ((node->is_independent() || node->is_partially_dependent()) &&
698 node->IsWeakRetainer()) { 731 node->IsWeakRetainer()) {
699 // Pending weak phantom handles die immediately. Everything else survives. 732 // Pending weak phantom handles die immediately. Everything else survives.
700 if (node->state() == Node::PENDING && 733 if (node->IsPendingPhantomResetHandle()) {
701 node->weakness_type() != FINALIZER_WEAK) { 734 node->ResetPhantomHandle();
735 ++number_of_phantom_handle_resets_;
736 } else if (node->IsPendingPhantomCallback()) {
702 node->CollectPhantomCallbackData(isolate(), 737 node->CollectPhantomCallbackData(isolate(),
703 &pending_phantom_callbacks_); 738 &pending_phantom_callbacks_);
704 } else { 739 } else {
705 v->VisitPointer(node->location()); 740 v->VisitPointer(node->location());
706 } 741 }
707 } 742 }
708 } 743 }
709 } 744 }
710 745
711 746
(...skipping 21 matching lines...) Expand all
733 } 768 }
734 769
735 770
736 void GlobalHandles::IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v) { 771 void GlobalHandles::IterateNewSpaceWeakUnmodifiedRoots(ObjectVisitor* v) {
737 for (int i = 0; i < new_space_nodes_.length(); ++i) { 772 for (int i = 0; i < new_space_nodes_.length(); ++i) {
738 Node* node = new_space_nodes_[i]; 773 Node* node = new_space_nodes_[i];
739 DCHECK(node->is_in_new_space_list()); 774 DCHECK(node->is_in_new_space_list());
740 if ((node->is_independent() || !node->is_active()) && 775 if ((node->is_independent() || !node->is_active()) &&
741 node->IsWeakRetainer()) { 776 node->IsWeakRetainer()) {
742 // Pending weak phantom handles die immediately. Everything else survives. 777 // Pending weak phantom handles die immediately. Everything else survives.
743 if (node->state() == Node::PENDING && 778 if (node->IsPendingPhantomResetHandle()) {
744 node->weakness_type() != FINALIZER_WEAK) { 779 node->ResetPhantomHandle();
780 ++number_of_phantom_handle_resets_;
781 } else if (node->IsPendingPhantomCallback()) {
745 node->CollectPhantomCallbackData(isolate(), 782 node->CollectPhantomCallbackData(isolate(),
746 &pending_phantom_callbacks_); 783 &pending_phantom_callbacks_);
747 } else { 784 } else {
748 v->VisitPointer(node->location()); 785 v->VisitPointer(node->location());
749 } 786 }
750 } 787 }
751 } 788 }
752 } 789 }
753 790
754 791
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after
1468 blocks_[block][offset] = object; 1505 blocks_[block][offset] = object;
1469 if (isolate->heap()->InNewSpace(object)) { 1506 if (isolate->heap()->InNewSpace(object)) {
1470 new_space_indices_.Add(size_); 1507 new_space_indices_.Add(size_);
1471 } 1508 }
1472 *index = size_++; 1509 *index = size_++;
1473 } 1510 }
1474 1511
1475 1512
1476 } // namespace internal 1513 } // namespace internal
1477 } // namespace v8 1514 } // namespace v8
OLDNEW
« no previous file with comments | « src/global-handles.h ('k') | test/cctest/test-global-handles.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698