| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 } | 51 } |
| 52 | 52 |
| 53 static inline bool IsStopped() { return state() == STOPPED; } | 53 static inline bool IsStopped() { return state() == STOPPED; } |
| 54 | 54 |
| 55 static bool WorthActivating(); | 55 static bool WorthActivating(); |
| 56 | 56 |
| 57 static void Start(); | 57 static void Start(); |
| 58 | 58 |
| 59 static void Stop(); | 59 static void Stop(); |
| 60 | 60 |
| 61 static void PrepareForScavenge(); |
| 62 |
| 63 static void UpdateMarkingStackAfterScavenge(); |
| 64 |
| 61 static void Hurry(); | 65 static void Hurry(); |
| 62 | 66 |
| 63 static void Finalize(); | 67 static void Finalize(); |
| 64 | 68 |
| 65 static void MarkingComplete(); | 69 static void MarkingComplete(); |
| 66 | 70 |
| 67 static const intptr_t kAllocatedThreshold = 1024; | 71 static const intptr_t kAllocatedThreshold = 1024; |
| 68 static const intptr_t kAllocationMarkingFactor = 8; | 72 static const intptr_t kAllocationMarkingFactor = 8; |
| 69 | 73 |
| 70 static void Step(intptr_t allocated); | 74 static void Step(intptr_t allocated); |
| 71 | 75 |
| 72 static inline void RestartIfNotMarking() { | 76 static inline void RestartIfNotMarking() { |
| 73 if (state_ == COMPLETE) { | 77 if (state_ == COMPLETE) { |
| 74 state_ = MARKING; | 78 state_ = MARKING; |
| 75 if (FLAG_trace_incremental_marking) { | 79 if (FLAG_trace_incremental_marking) { |
| 76 PrintF("[IncrementalMarking] Restarting (new grey objects)\n"); | 80 PrintF("[IncrementalMarking] Restarting (new grey objects)\n"); |
| 77 } | 81 } |
| 78 } | 82 } |
| 79 } | 83 } |
| 80 | 84 |
| 81 static inline void RecordWrite(HeapObject* obj, Object* value) { | 85 static inline void RecordWrite(HeapObject* obj, Object* value) { |
| 82 if (!IsStopped() && value->IsHeapObject()) { | 86 if (!IsStopped() && value->IsHeapObject()) { |
| 83 MarkBit value_bit = Marking::MarkBitFrom(HeapObject::cast(value)); | 87 MarkBit value_bit = Marking::MarkBitFrom(HeapObject::cast(value)); |
| 84 if (IsWhite(value_bit)) { | 88 if (IsWhite(value_bit)) { |
| 85 MarkBit obj_bit = Marking::MarkBitFrom(obj); | 89 MarkBit obj_bit = Marking::MarkBitFrom(obj); |
| 86 if (IsBlack(obj_bit)) { | 90 if (IsBlack(obj_bit)) { |
| 87 BlackToGrey(obj, obj_bit); | 91 BlackToGreyAndPush(obj, obj_bit); |
| 88 RestartIfNotMarking(); | 92 RestartIfNotMarking(); |
| 89 } | 93 } |
| 90 } | 94 } |
| 91 } | 95 } |
| 92 } | 96 } |
| 93 | 97 |
| 94 static inline void RecordWriteOf(HeapObject* value) { | 98 static inline void RecordWriteOf(HeapObject* value) { |
| 95 if (state_ != STOPPED) { | 99 if (state_ != STOPPED) { |
| 96 MarkBit value_bit = Marking::MarkBitFrom(value); | 100 MarkBit value_bit = Marking::MarkBitFrom(value); |
| 97 if (IsWhite(value_bit)) { | 101 if (IsWhite(value_bit)) { |
| 98 WhiteToGrey(value, value_bit); | 102 WhiteToGreyAndPush(value, value_bit); |
| 99 RestartIfNotMarking(); | 103 RestartIfNotMarking(); |
| 100 } | 104 } |
| 101 } | 105 } |
| 102 } | 106 } |
| 103 | 107 |
| 104 | 108 |
| 105 static inline void RecordWrites(HeapObject* obj) { | 109 static inline void RecordWrites(HeapObject* obj) { |
| 106 if (!IsStopped()) { | 110 if (!IsStopped()) { |
| 107 MarkBit obj_bit = Marking::MarkBitFrom(obj); | 111 MarkBit obj_bit = Marking::MarkBitFrom(obj); |
| 108 if (IsBlack(obj_bit)) { | 112 if (IsBlack(obj_bit)) { |
| 109 BlackToGrey(obj, obj_bit); | 113 BlackToGreyAndPush(obj, obj_bit); |
| 110 RestartIfNotMarking(); | 114 RestartIfNotMarking(); |
| 111 } | 115 } |
| 112 } | 116 } |
| 113 } | 117 } |
| 114 | 118 |
| 115 // Impossible markbits: 01 | 119 // Impossible markbits: 01 |
| 116 static inline bool IsImpossible(MarkBit mark_bit) { | 120 static inline bool IsImpossible(MarkBit mark_bit) { |
| 117 return !mark_bit.Get() && mark_bit.Next().Get(); | 121 return !mark_bit.Get() && mark_bit.Next().Get(); |
| 118 } | 122 } |
| 119 | 123 |
| 120 // Black markbits: 10 - this is required by the sweeper. | 124 // Black markbits: 10 - this is required by the sweeper. |
| 121 static inline bool IsBlack(MarkBit mark_bit) { | 125 static inline bool IsBlack(MarkBit mark_bit) { |
| 122 ASSERT(!IsImpossible(mark_bit)); | 126 ASSERT(!IsImpossible(mark_bit)); |
| 123 return mark_bit.Get() && !mark_bit.Next().Get(); | 127 return mark_bit.Get() && !mark_bit.Next().Get(); |
| 124 } | 128 } |
| 125 | 129 |
| 126 // White markbits: 00 - this is required by the mark bit clearer. | 130 // White markbits: 00 - this is required by the mark bit clearer. |
| 127 static inline bool IsWhite(MarkBit mark_bit) { | 131 static inline bool IsWhite(MarkBit mark_bit) { |
| 128 ASSERT(!IsImpossible(mark_bit)); | 132 ASSERT(!IsImpossible(mark_bit)); |
| 129 return !mark_bit.Get(); | 133 return !mark_bit.Get(); |
| 130 } | 134 } |
| 131 | 135 |
| 132 // Grey markbits: 11 | 136 // Grey markbits: 11 |
| 133 static inline bool IsGrey(MarkBit mark_bit) { | 137 static inline bool IsGrey(MarkBit mark_bit) { |
| 134 ASSERT(!IsImpossible(mark_bit)); | 138 ASSERT(!IsImpossible(mark_bit)); |
| 135 return mark_bit.Get() && mark_bit.Next().Get(); | 139 return mark_bit.Get() && mark_bit.Next().Get(); |
| 136 } | 140 } |
| 137 | 141 |
| 138 static inline void BlackToGrey(HeapObject* obj, MarkBit mark_bit) { | 142 static inline void BlackToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { |
| 139 ASSERT(Marking::MarkBitFrom(obj) == mark_bit); | 143 ASSERT(Marking::MarkBitFrom(obj) == mark_bit); |
| 140 ASSERT(obj->Size() >= 2*kPointerSize); | 144 ASSERT(obj->Size() >= 2*kPointerSize); |
| 141 ASSERT(!IsStopped()); | 145 ASSERT(!IsStopped()); |
| 142 ASSERT(IsBlack(mark_bit)); | 146 ASSERT(IsBlack(mark_bit)); |
| 143 mark_bit.Next().Set(); | 147 mark_bit.Next().Set(); |
| 144 ASSERT(IsGrey(mark_bit)); | 148 ASSERT(IsGrey(mark_bit)); |
| 145 | 149 |
| 146 marking_stack_.Push(obj); | 150 marking_stack_.Push(obj); |
| 147 ASSERT(!marking_stack_.overflowed()); | 151 ASSERT(!marking_stack_.overflowed()); |
| 148 } | 152 } |
| 149 | 153 |
| 154 static inline void WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) { |
| 155 WhiteToGrey(obj, mark_bit); |
| 156 marking_stack_.Push(obj); |
| 157 ASSERT(!marking_stack_.overflowed()); |
| 158 } |
| 159 |
| 150 static inline void WhiteToGrey(HeapObject* obj, MarkBit mark_bit) { | 160 static inline void WhiteToGrey(HeapObject* obj, MarkBit mark_bit) { |
| 151 ASSERT(Marking::MarkBitFrom(obj) == mark_bit); | 161 ASSERT(Marking::MarkBitFrom(obj) == mark_bit); |
| 152 ASSERT(obj->Size() >= 2*kPointerSize); | 162 ASSERT(obj->Size() >= 2*kPointerSize); |
| 153 ASSERT(!IsStopped()); | 163 ASSERT(!IsStopped()); |
| 154 ASSERT(IsWhite(mark_bit)); | 164 ASSERT(IsWhite(mark_bit)); |
| 155 mark_bit.Set(); | 165 mark_bit.Set(); |
| 156 mark_bit.Next().Set(); | 166 mark_bit.Next().Set(); |
| 157 ASSERT(IsGrey(mark_bit)); | 167 ASSERT(IsGrey(mark_bit)); |
| 158 | |
| 159 marking_stack_.Push(obj); | |
| 160 ASSERT(!marking_stack_.overflowed()); | |
| 161 } | 168 } |
| 162 | 169 |
| 163 static inline void MarkBlack(MarkBit mark_bit) { | 170 static inline void MarkBlack(MarkBit mark_bit) { |
| 164 mark_bit.Set(); | 171 mark_bit.Set(); |
| 165 mark_bit.Next().Clear(); | 172 mark_bit.Next().Clear(); |
| 166 ASSERT(IsBlack(mark_bit)); | 173 ASSERT(IsBlack(mark_bit)); |
| 167 } | 174 } |
| 168 | 175 |
| 169 static inline const char* ColorStr(MarkBit mark_bit) { | 176 static inline const char* ColorStr(MarkBit mark_bit) { |
| 170 if (IsBlack(mark_bit)) return "black"; | 177 if (IsBlack(mark_bit)) return "black"; |
| 171 if (IsWhite(mark_bit)) return "white"; | 178 if (IsWhite(mark_bit)) return "white"; |
| 172 if (IsGrey(mark_bit)) return "grey"; | 179 if (IsGrey(mark_bit)) return "grey"; |
| 173 UNREACHABLE(); | 180 UNREACHABLE(); |
| 174 return "???"; | 181 return "???"; |
| 175 } | 182 } |
| 176 | 183 |
| 184 enum ObjectColor { |
| 185 BLACK_OBJECT, |
| 186 WHITE_OBJECT, |
| 187 GREY_OBJECT, |
| 188 IMPOSSIBLE_COLOR |
| 189 }; |
| 190 |
| 191 static inline ObjectColor Color(HeapObject* obj) { |
| 192 MarkBit mark_bit = Marking::MarkBitFrom(obj); |
| 193 if (IsBlack(mark_bit)) return BLACK_OBJECT; |
| 194 if (IsWhite(mark_bit)) return WHITE_OBJECT; |
| 195 if (IsGrey(mark_bit)) return GREY_OBJECT; |
| 196 UNREACHABLE(); |
| 197 return IMPOSSIBLE_COLOR; |
| 198 } |
| 199 |
| 177 private: | 200 private: |
| 178 static State state_; | 201 static State state_; |
| 179 static MarkingStack marking_stack_; | 202 static MarkingStack marking_stack_; |
| 180 }; | 203 }; |
| 181 | 204 |
| 182 } } // namespace v8::internal | 205 } } // namespace v8::internal |
| 183 | 206 |
| 184 #endif // V8_INCREMENTAL_MARKING_H_ | 207 #endif // V8_INCREMENTAL_MARKING_H_ |
| OLD | NEW |