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

Side by Side Diff: src/heap/marking.h

Issue 2860323003: [heap] Reland "Make non-atomic markbit operations consistent with atomic ones." (Closed)
Patch Set: fix Created 3 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/heap/mark-compact-inl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #ifndef V8_MARKING_H 5 #ifndef V8_MARKING_H
6 #define V8_MARKING_H 6 #define V8_MARKING_H
7 7
8 #include "src/base/atomic-utils.h" 8 #include "src/base/atomic-utils.h"
9 #include "src/utils.h" 9 #include "src/utils.h"
10 10
(...skipping 20 matching lines...) Expand all
31 private: 31 private:
32 inline MarkBit Next() { 32 inline MarkBit Next() {
33 CellType new_mask = mask_ << 1; 33 CellType new_mask = mask_ << 1;
34 if (new_mask == 0) { 34 if (new_mask == 0) {
35 return MarkBit(cell_ + 1, 1); 35 return MarkBit(cell_ + 1, 1);
36 } else { 36 } else {
37 return MarkBit(cell_, new_mask); 37 return MarkBit(cell_, new_mask);
38 } 38 }
39 } 39 }
40 40
41 // The function returns true if it succeeded to
42 // transition the bit from 0 to 1.
41 template <AccessMode mode = NON_ATOMIC> 43 template <AccessMode mode = NON_ATOMIC>
42 inline bool Set(); 44 inline bool Set();
43 45
44 template <AccessMode mode = NON_ATOMIC> 46 template <AccessMode mode = NON_ATOMIC>
45 inline bool Get(); 47 inline bool Get();
46 48
49 // The function returns true if it succeeded to
50 // transition the bit from 1 to 0.
47 template <AccessMode mode = NON_ATOMIC> 51 template <AccessMode mode = NON_ATOMIC>
48 inline bool Clear(); 52 inline bool Clear();
49 53
50 base::Atomic32* cell_; 54 base::Atomic32* cell_;
51 base::Atomic32 mask_; 55 base::Atomic32 mask_;
52 56
53 friend class IncrementalMarking; 57 friend class IncrementalMarking;
54 friend class ConcurrentMarkingMarkbits; 58 friend class ConcurrentMarkingMarkbits;
55 friend class Marking; 59 friend class Marking;
56 }; 60 };
57 61
58 template <> 62 template <>
59 inline bool MarkBit::Set<MarkBit::NON_ATOMIC>() { 63 inline bool MarkBit::Set<MarkBit::NON_ATOMIC>() {
60 *cell_ |= mask_; 64 base::Atomic32 old_value = *cell_;
61 return true; 65 *cell_ = old_value | mask_;
66 return (old_value & mask_) == 0;
62 } 67 }
63 68
64 template <> 69 template <>
65 inline bool MarkBit::Set<MarkBit::ATOMIC>() { 70 inline bool MarkBit::Set<MarkBit::ATOMIC>() {
66 base::Atomic32 old_value; 71 base::Atomic32 old_value;
67 base::Atomic32 new_value; 72 base::Atomic32 new_value;
68 do { 73 do {
69 old_value = base::NoBarrier_Load(cell_); 74 old_value = base::NoBarrier_Load(cell_);
70 if (old_value & mask_) return false; 75 if (old_value & mask_) return false;
71 new_value = old_value | mask_; 76 new_value = old_value | mask_;
72 } while (base::Release_CompareAndSwap(cell_, old_value, new_value) != 77 } while (base::Release_CompareAndSwap(cell_, old_value, new_value) !=
73 old_value); 78 old_value);
74 return true; 79 return true;
75 } 80 }
76 81
77 template <> 82 template <>
78 inline bool MarkBit::Get<MarkBit::NON_ATOMIC>() { 83 inline bool MarkBit::Get<MarkBit::NON_ATOMIC>() {
79 return (base::NoBarrier_Load(cell_) & mask_) != 0; 84 return (base::NoBarrier_Load(cell_) & mask_) != 0;
80 } 85 }
81 86
82 template <> 87 template <>
83 inline bool MarkBit::Get<MarkBit::ATOMIC>() { 88 inline bool MarkBit::Get<MarkBit::ATOMIC>() {
84 return (base::Acquire_Load(cell_) & mask_) != 0; 89 return (base::Acquire_Load(cell_) & mask_) != 0;
85 } 90 }
86 91
87 template <> 92 template <>
88 inline bool MarkBit::Clear<MarkBit::NON_ATOMIC>() { 93 inline bool MarkBit::Clear<MarkBit::NON_ATOMIC>() {
89 *cell_ &= ~mask_; 94 base::Atomic32 old_value = *cell_;
90 return true; 95 *cell_ = old_value & ~mask_;
96 return (old_value & mask_) == mask_;
91 } 97 }
92 98
93 template <> 99 template <>
94 inline bool MarkBit::Clear<MarkBit::ATOMIC>() { 100 inline bool MarkBit::Clear<MarkBit::ATOMIC>() {
95 base::Atomic32 old_value; 101 base::Atomic32 old_value;
96 base::Atomic32 new_value; 102 base::Atomic32 new_value;
97 do { 103 do {
98 old_value = base::NoBarrier_Load(cell_); 104 old_value = base::NoBarrier_Load(cell_);
99 if (!(old_value & mask_)) return false; 105 if (!(old_value & mask_)) return false;
100 new_value = old_value & ~mask_; 106 new_value = old_value & ~mask_;
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 411
406 template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC> 412 template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC>
407 INLINE(static bool BlackToGrey(MarkBit markbit)) { 413 INLINE(static bool BlackToGrey(MarkBit markbit)) {
408 STATIC_ASSERT(mode == MarkBit::NON_ATOMIC); 414 STATIC_ASSERT(mode == MarkBit::NON_ATOMIC);
409 DCHECK(IsBlack(markbit)); 415 DCHECK(IsBlack(markbit));
410 return markbit.Next().Clear<mode>(); 416 return markbit.Next().Clear<mode>();
411 } 417 }
412 418
413 template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC> 419 template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC>
414 INLINE(static bool WhiteToGrey(MarkBit markbit)) { 420 INLINE(static bool WhiteToGrey(MarkBit markbit)) {
415 DCHECK(mode == MarkBit::ATOMIC || IsWhite(markbit));
416 return markbit.Set<mode>(); 421 return markbit.Set<mode>();
417 } 422 }
418 423
419 // Warning: this method is not safe in general in concurrent scenarios.
420 // If you know that nobody else will change the bits on the given location
421 // then you may use it.
422 template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC> 424 template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC>
423 INLINE(static void WhiteToBlack(MarkBit markbit)) { 425 INLINE(static bool WhiteToBlack(MarkBit markbit)) {
424 DCHECK(mode == MarkBit::ATOMIC || IsWhite(markbit)); 426 return markbit.Set<mode>() && markbit.Next().Set<mode>();
425 markbit.Set<mode>();
426 markbit.Next().Set<mode>();
427 } 427 }
428 428
429 template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC> 429 template <MarkBit::AccessMode mode = MarkBit::NON_ATOMIC>
430 INLINE(static bool GreyToBlack(MarkBit markbit)) { 430 INLINE(static bool GreyToBlack(MarkBit markbit)) {
431 DCHECK(mode == MarkBit::ATOMIC || IsGrey(markbit)); 431 return markbit.Get<mode>() && markbit.Next().Set<mode>();
432 return markbit.Next().Set<mode>();
433 } 432 }
434 433
435 enum ObjectColor { 434 enum ObjectColor {
436 BLACK_OBJECT, 435 BLACK_OBJECT,
437 WHITE_OBJECT, 436 WHITE_OBJECT,
438 GREY_OBJECT, 437 GREY_OBJECT,
439 IMPOSSIBLE_COLOR 438 IMPOSSIBLE_COLOR
440 }; 439 };
441 440
442 static const char* ColorName(ObjectColor color) { 441 static const char* ColorName(ObjectColor color) {
(...skipping 19 matching lines...) Expand all
462 } 461 }
463 462
464 private: 463 private:
465 DISALLOW_IMPLICIT_CONSTRUCTORS(Marking); 464 DISALLOW_IMPLICIT_CONSTRUCTORS(Marking);
466 }; 465 };
467 466
468 } // namespace internal 467 } // namespace internal
469 } // namespace v8 468 } // namespace v8
470 469
471 #endif // V8_MARKING_H_ 470 #endif // V8_MARKING_H_
OLDNEW
« no previous file with comments | « src/heap/mark-compact-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698