OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 | 139 |
140 private: | 140 private: |
141 ThreadState* state_; | 141 ThreadState* state_; |
142 }; | 142 }; |
143 | 143 |
144 class SweepForbiddenScope final { | 144 class SweepForbiddenScope final { |
145 STACK_ALLOCATED(); | 145 STACK_ALLOCATED(); |
146 | 146 |
147 public: | 147 public: |
148 explicit SweepForbiddenScope(ThreadState* state) : state_(state) { | 148 explicit SweepForbiddenScope(ThreadState* state) : state_(state) { |
149 ASSERT(!state_->sweep_forbidden_); | 149 DCHECK(!state_->sweep_forbidden_); |
150 state_->sweep_forbidden_ = true; | 150 state_->sweep_forbidden_ = true; |
151 } | 151 } |
152 ~SweepForbiddenScope() { | 152 ~SweepForbiddenScope() { |
153 ASSERT(state_->sweep_forbidden_); | 153 DCHECK(state_->sweep_forbidden_); |
154 state_->sweep_forbidden_ = false; | 154 state_->sweep_forbidden_ = false; |
155 } | 155 } |
156 | 156 |
157 private: | 157 private: |
158 ThreadState* state_; | 158 ThreadState* state_; |
159 }; | 159 }; |
160 | 160 |
161 // Used to denote when access to unmarked objects is allowed but we shouldn't | 161 // Used to denote when access to unmarked objects is allowed but we shouldn't |
162 // ressurect it by making new references (e.g. during weak processing and pre | 162 // ressurect it by making new references (e.g. during weak processing and pre |
163 // finalizer). | 163 // finalizer). |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 void EnterSafePoint(BlinkGC::StackState, void*); | 351 void EnterSafePoint(BlinkGC::StackState, void*); |
352 void LeaveSafePoint(); | 352 void LeaveSafePoint(); |
353 | 353 |
354 void RecordStackEnd(intptr_t* end_of_stack) { end_of_stack_ = end_of_stack; } | 354 void RecordStackEnd(intptr_t* end_of_stack) { end_of_stack_ = end_of_stack; } |
355 NO_SANITIZE_ADDRESS void CopyStackUntilSafePointScope(); | 355 NO_SANITIZE_ADDRESS void CopyStackUntilSafePointScope(); |
356 | 356 |
357 // Get one of the heap structures for this thread. | 357 // Get one of the heap structures for this thread. |
358 // The thread heap is split into multiple heap parts based on object types | 358 // The thread heap is split into multiple heap parts based on object types |
359 // and object sizes. | 359 // and object sizes. |
360 BaseArena* Arena(int arena_index) const { | 360 BaseArena* Arena(int arena_index) const { |
361 ASSERT(0 <= arena_index); | 361 DCHECK_LE(0, arena_index); |
362 ASSERT(arena_index < BlinkGC::kNumberOfArenas); | 362 DCHECK_LT(arena_index, BlinkGC::kNumberOfArenas); |
363 return arenas_[arena_index]; | 363 return arenas_[arena_index]; |
364 } | 364 } |
365 | 365 |
366 #if DCHECK_IS_ON() | 366 #if DCHECK_IS_ON() |
367 // Infrastructure to determine if an address is within one of the | 367 // Infrastructure to determine if an address is within one of the |
368 // address ranges for the Blink heap. If the address is in the Blink | 368 // address ranges for the Blink heap. If the address is in the Blink |
369 // heap the containing heap page is returned. | 369 // heap the containing heap page is returned. |
370 BasePage* FindPageFromAddress(Address); | 370 BasePage* FindPageFromAddress(Address); |
371 BasePage* FindPageFromAddress(const void* pointer) { | 371 BasePage* FindPageFromAddress(const void* pointer) { |
372 return FindPageFromAddress( | 372 return FindPageFromAddress( |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 } | 425 } |
426 | 426 |
427 // By entering a gc-forbidden scope, conservative GCs will not | 427 // By entering a gc-forbidden scope, conservative GCs will not |
428 // be allowed while handling an out-of-line allocation request. | 428 // be allowed while handling an out-of-line allocation request. |
429 // Intended used when constructing subclasses of GC mixins, where | 429 // Intended used when constructing subclasses of GC mixins, where |
430 // the object being constructed cannot be safely traced & marked | 430 // the object being constructed cannot be safely traced & marked |
431 // fully should a GC be allowed while its subclasses are being | 431 // fully should a GC be allowed while its subclasses are being |
432 // constructed. | 432 // constructed. |
433 void EnterGCForbiddenScopeIfNeeded( | 433 void EnterGCForbiddenScopeIfNeeded( |
434 GarbageCollectedMixinConstructorMarker* gc_mixin_marker) { | 434 GarbageCollectedMixinConstructorMarker* gc_mixin_marker) { |
435 ASSERT(CheckThread()); | 435 DCHECK(CheckThread()); |
436 if (!gc_mixin_marker_) { | 436 if (!gc_mixin_marker_) { |
437 EnterMixinConstructionScope(); | 437 EnterMixinConstructionScope(); |
438 gc_mixin_marker_ = gc_mixin_marker; | 438 gc_mixin_marker_ = gc_mixin_marker; |
439 } | 439 } |
440 } | 440 } |
441 void LeaveGCForbiddenScopeIfNeeded( | 441 void LeaveGCForbiddenScopeIfNeeded( |
442 GarbageCollectedMixinConstructorMarker* gc_mixin_marker) { | 442 GarbageCollectedMixinConstructorMarker* gc_mixin_marker) { |
443 ASSERT(CheckThread()); | 443 DCHECK(CheckThread()); |
444 if (gc_mixin_marker_ == gc_mixin_marker) { | 444 if (gc_mixin_marker_ == gc_mixin_marker) { |
445 LeaveMixinConstructionScope(); | 445 LeaveMixinConstructionScope(); |
446 gc_mixin_marker_ = nullptr; | 446 gc_mixin_marker_ = nullptr; |
447 } | 447 } |
448 } | 448 } |
449 | 449 |
450 // vectorBackingArena() returns an arena that the vector allocation should | 450 // vectorBackingArena() returns an arena that the vector allocation should |
451 // use. We have four vector arenas and want to choose the best arena here. | 451 // use. We have four vector arenas and want to choose the best arena here. |
452 // | 452 // |
453 // The goal is to improve the succession rate where expand and | 453 // The goal is to improve the succession rate where expand and |
(...skipping 13 matching lines...) Expand all Loading... |
467 // To implement the heuristics, we add an arenaAge to each arena. The arenaAge | 467 // To implement the heuristics, we add an arenaAge to each arena. The arenaAge |
468 // is updated if: | 468 // is updated if: |
469 // | 469 // |
470 // - a vector on the arena is expanded; or | 470 // - a vector on the arena is expanded; or |
471 // - a vector that meets the condition (*) is allocated on the arena | 471 // - a vector that meets the condition (*) is allocated on the arena |
472 // | 472 // |
473 // (*) More than 33% of the same type of vectors have been promptly | 473 // (*) More than 33% of the same type of vectors have been promptly |
474 // freed since the last GC. | 474 // freed since the last GC. |
475 // | 475 // |
476 BaseArena* VectorBackingArena(size_t gc_info_index) { | 476 BaseArena* VectorBackingArena(size_t gc_info_index) { |
477 ASSERT(CheckThread()); | 477 DCHECK(CheckThread()); |
478 size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask; | 478 size_t entry_index = gc_info_index & kLikelyToBePromptlyFreedArrayMask; |
479 --likely_to_be_promptly_freed_[entry_index]; | 479 --likely_to_be_promptly_freed_[entry_index]; |
480 int arena_index = vector_backing_arena_index_; | 480 int arena_index = vector_backing_arena_index_; |
481 // If m_likelyToBePromptlyFreed[entryIndex] > 0, that means that | 481 // If m_likelyToBePromptlyFreed[entryIndex] > 0, that means that |
482 // more than 33% of vectors of the type have been promptly freed | 482 // more than 33% of vectors of the type have been promptly freed |
483 // since the last GC. | 483 // since the last GC. |
484 if (likely_to_be_promptly_freed_[entry_index] > 0) { | 484 if (likely_to_be_promptly_freed_[entry_index] > 0) { |
485 arena_ages_[arena_index] = ++current_arena_ages_; | 485 arena_ages_[arena_index] = ++current_arena_ages_; |
486 vector_backing_arena_index_ = | 486 vector_backing_arena_index_ = |
487 ArenaIndexOfVectorArenaLeastRecentlyExpanded( | 487 ArenaIndexOfVectorArenaLeastRecentlyExpanded( |
488 BlinkGC::kVector1ArenaIndex, BlinkGC::kVector4ArenaIndex); | 488 BlinkGC::kVector1ArenaIndex, BlinkGC::kVector4ArenaIndex); |
489 } | 489 } |
490 ASSERT(IsVectorArenaIndex(arena_index)); | 490 DCHECK(IsVectorArenaIndex(arena_index)); |
491 return arenas_[arena_index]; | 491 return arenas_[arena_index]; |
492 } | 492 } |
493 BaseArena* ExpandedVectorBackingArena(size_t gc_info_index); | 493 BaseArena* ExpandedVectorBackingArena(size_t gc_info_index); |
494 static bool IsVectorArenaIndex(int arena_index) { | 494 static bool IsVectorArenaIndex(int arena_index) { |
495 return BlinkGC::kVector1ArenaIndex <= arena_index && | 495 return BlinkGC::kVector1ArenaIndex <= arena_index && |
496 arena_index <= BlinkGC::kVector4ArenaIndex; | 496 arena_index <= BlinkGC::kVector4ArenaIndex; |
497 } | 497 } |
498 void AllocationPointAdjusted(int arena_index); | 498 void AllocationPointAdjusted(int arena_index); |
499 void PromptlyFreed(size_t gc_info_index); | 499 void PromptlyFreed(size_t gc_info_index); |
500 | 500 |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 template <ThreadAffinity affinity> | 713 template <ThreadAffinity affinity> |
714 class ThreadStateFor; | 714 class ThreadStateFor; |
715 | 715 |
716 template <> | 716 template <> |
717 class ThreadStateFor<kMainThreadOnly> { | 717 class ThreadStateFor<kMainThreadOnly> { |
718 STATIC_ONLY(ThreadStateFor); | 718 STATIC_ONLY(ThreadStateFor); |
719 | 719 |
720 public: | 720 public: |
721 static ThreadState* GetState() { | 721 static ThreadState* GetState() { |
722 // This specialization must only be used from the main thread. | 722 // This specialization must only be used from the main thread. |
723 ASSERT(ThreadState::Current()->IsMainThread()); | 723 DCHECK(ThreadState::Current()->IsMainThread()); |
724 return ThreadState::MainThreadState(); | 724 return ThreadState::MainThreadState(); |
725 } | 725 } |
726 }; | 726 }; |
727 | 727 |
728 template <> | 728 template <> |
729 class ThreadStateFor<kAnyThread> { | 729 class ThreadStateFor<kAnyThread> { |
730 STATIC_ONLY(ThreadStateFor); | 730 STATIC_ONLY(ThreadStateFor); |
731 | 731 |
732 public: | 732 public: |
733 static ThreadState* GetState() { return ThreadState::Current(); } | 733 static ThreadState* GetState() { return ThreadState::Current(); } |
734 }; | 734 }; |
735 | 735 |
736 } // namespace blink | 736 } // namespace blink |
737 | 737 |
738 #endif // ThreadState_h | 738 #endif // ThreadState_h |
OLD | NEW |