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

Side by Side Diff: src/incremental-marking.cc

Issue 6715028: Preserve marking bits across scavenges if incremental marker is running. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: fix review comments, add more tracing Created 9 years, 9 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
« no previous file with comments | « src/incremental-marking.h ('k') | src/mark-compact.h » ('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 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 19 matching lines...) Expand all
30 #include "incremental-marking.h" 30 #include "incremental-marking.h"
31 31
32 #include "code-stubs.h" 32 #include "code-stubs.h"
33 33
34 namespace v8 { 34 namespace v8 {
35 namespace internal { 35 namespace internal {
36 36
37 IncrementalMarking::State IncrementalMarking::state_ = STOPPED; 37 IncrementalMarking::State IncrementalMarking::state_ = STOPPED;
38 MarkingStack IncrementalMarking::marking_stack_; 38 MarkingStack IncrementalMarking::marking_stack_;
39 39
40 static double steps_took = 0;
41 static int steps_count = 0;
42
40 static intptr_t allocated = 0; 43 static intptr_t allocated = 0;
41 44
42 class IncrementalMarkingMarkingVisitor : public ObjectVisitor { 45 class IncrementalMarkingMarkingVisitor : public ObjectVisitor {
43 public: 46 public:
44 void VisitPointer(Object** p) { 47 void VisitPointer(Object** p) {
45 MarkObjectByPointer(p); 48 MarkObjectByPointer(p);
46 } 49 }
47 50
48 void VisitPointers(Object** start, Object** end) { 51 void VisitPointers(Object** start, Object** end) {
49 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); 52 for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
50 } 53 }
51 54
52 private: 55 private:
53 // Mark object pointed to by p. 56 // Mark object pointed to by p.
54 INLINE(static void MarkObjectByPointer(Object** p)) { 57 INLINE(static void MarkObjectByPointer(Object** p)) {
55 Object* obj = *p; 58 Object* obj = *p;
56 if (obj->IsHeapObject()) { 59 if (obj->IsHeapObject()) {
57 HeapObject* heap_object = HeapObject::cast(obj); 60 HeapObject* heap_object = HeapObject::cast(obj);
58 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); 61 MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
59 if (IncrementalMarking::IsWhite(mark_bit)) { 62 if (IncrementalMarking::IsWhite(mark_bit)) {
60 IncrementalMarking::WhiteToGrey(heap_object, mark_bit); 63 IncrementalMarking::WhiteToGreyAndPush(heap_object, mark_bit);
61 } 64 }
62 } 65 }
63 } 66 }
64 }; 67 };
65 68
66 69
67 static IncrementalMarkingMarkingVisitor marking_visitor; 70 static IncrementalMarkingMarkingVisitor marking_visitor;
68 71
69 class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor { 72 class IncrementalMarkingRootMarkingVisitor : public ObjectVisitor {
70 public: 73 public:
71 void VisitPointer(Object** p) { 74 void VisitPointer(Object** p) {
72 MarkObjectByPointer(p); 75 MarkObjectByPointer(p);
73 } 76 }
74 77
75 void VisitPointers(Object** start, Object** end) { 78 void VisitPointers(Object** start, Object** end) {
76 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); 79 for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
77 } 80 }
78 81
79 private: 82 private:
80 void MarkObjectByPointer(Object** p) { 83 void MarkObjectByPointer(Object** p) {
81 Object* obj = *p; 84 Object* obj = *p;
82 if (!obj->IsHeapObject()) return; 85 if (!obj->IsHeapObject()) return;
83 86
84 HeapObject* heap_object = HeapObject::cast(obj); 87 HeapObject* heap_object = HeapObject::cast(obj);
85 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); 88 MarkBit mark_bit = Marking::MarkBitFrom(heap_object);
86 if (IncrementalMarking::IsWhite(mark_bit)) { 89 if (IncrementalMarking::IsWhite(mark_bit)) {
87 IncrementalMarking::WhiteToGrey(heap_object, mark_bit); 90 IncrementalMarking::WhiteToGreyAndPush(heap_object, mark_bit);
88 } 91 }
89 } 92 }
90 }; 93 };
91 94
92 95
93 static void ClearMarkbits(PagedSpace* space) { 96 static void ClearMarkbits(PagedSpace* space) {
94 PageIterator it(space); 97 PageIterator it(space);
95 98
96 while (it.has_next()) { 99 while (it.has_next()) {
97 Page* p = it.next(); 100 Page* p = it.next();
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 CodeStub::IncrementalMarkingRecordWrite) { 159 CodeStub::IncrementalMarkingRecordWrite) {
157 Object* e = stubs->ValueAt(i); 160 Object* e = stubs->ValueAt(i);
158 if (e->IsCode()) { 161 if (e->IsCode()) {
159 IncrementalMarkingRecordWriteStub::Patch(Code::cast(e), enable); 162 IncrementalMarkingRecordWriteStub::Patch(Code::cast(e), enable);
160 } 163 }
161 } 164 }
162 } 165 }
163 } 166 }
164 } 167 }
165 168
169 static VirtualMemory* marking_stack_memory = NULL;
170
171 static void EnsureMarkingStackIsCommitted() {
172 if (marking_stack_memory == NULL) {
173 marking_stack_memory = new VirtualMemory(4*MB);
174 marking_stack_memory->Commit(
175 reinterpret_cast<Address>(marking_stack_memory->address()),
176 marking_stack_memory->size(),
177 false); // Not executable.
178 }
179 }
180
166 181
167 void IncrementalMarking::Start() { 182 void IncrementalMarking::Start() {
168 if (FLAG_trace_incremental_marking) { 183 if (FLAG_trace_incremental_marking) {
169 PrintF("[IncrementalMarking] Start\n"); 184 PrintF("[IncrementalMarking] Start\n");
170 } 185 }
171 ASSERT(FLAG_incremental_marking); 186 ASSERT(FLAG_incremental_marking);
172 ASSERT(state_ == STOPPED); 187 ASSERT(state_ == STOPPED);
173 state_ = MARKING; 188 state_ = MARKING;
189 steps_took = 0;
190 steps_count = 0;
174 191
175 PatchIncrementalMarkingRecordWriteStubs(true); 192 PatchIncrementalMarkingRecordWriteStubs(true);
176 193
177 Heap::EnsureFromSpaceIsCommitted(); 194 EnsureMarkingStackIsCommitted();
178 195
179 // Initialize marking stack. 196 // Initialize marking stack.
180 marking_stack_.Initialize(Heap::new_space()->FromSpaceLow(), 197 Address addr = static_cast<Address>(marking_stack_memory->address());
181 Heap::new_space()->FromSpaceHigh()); 198 marking_stack_.Initialize(addr,
199 addr + marking_stack_memory->size());
182 200
183 // Clear markbits. 201 // Clear markbits.
184 Address new_space_bottom = Heap::new_space()->bottom(); 202 Address new_space_low = Heap::new_space()->ToSpaceLow();
185 uintptr_t new_space_size = 203 Address new_space_high = Heap::new_space()->ToSpaceHigh();
186 RoundUp(Heap::new_space()->top() - new_space_bottom, 32 * kPointerSize); 204 Marking::ClearRange(new_space_low,
187 205 static_cast<int>(new_space_high - new_space_low));
188 Marking::ClearRange(new_space_bottom, new_space_size);
189 206
190 ClearMarkbits(); 207 ClearMarkbits();
191 208
192 #ifdef DEBUG 209 #ifdef DEBUG
193 VerifyMarkbitsAreClean(); 210 VerifyMarkbitsAreClean();
194 #endif 211 #endif
195 212
196 // Mark strong roots grey. 213 // Mark strong roots grey.
197 IncrementalMarkingRootMarkingVisitor visitor; 214 IncrementalMarkingRootMarkingVisitor visitor;
198 Heap::IterateStrongRoots(&visitor, VISIT_ONLY_STRONG); 215 Heap::IterateStrongRoots(&visitor, VISIT_ONLY_STRONG);
199 216
200 // Ready to start incremental marking. 217 // Ready to start incremental marking.
201 if (FLAG_trace_incremental_marking) { 218 if (FLAG_trace_incremental_marking) {
202 PrintF("[IncrementalMarking] Running\n"); 219 PrintF("[IncrementalMarking] Running\n");
203 } 220 }
204 } 221 }
205 222
206 223
224 void IncrementalMarking::PrepareForScavenge() {
225 if (IsStopped()) return;
226
227 Address new_space_low = Heap::new_space()->FromSpaceLow();
228 Address new_space_high = Heap::new_space()->FromSpaceHigh();
229 Marking::ClearRange(new_space_low,
230 static_cast<int>(new_space_high - new_space_low));
231 }
232
233
234 void IncrementalMarking::UpdateMarkingStackAfterScavenge() {
235 if (IsStopped()) return;
236
237 HeapObject** current = marking_stack_.low();
238 HeapObject** top = marking_stack_.top();
239 HeapObject** new_top = current;
240
241 while (current < top) {
242 HeapObject* obj = *current++;
243 if (Heap::InNewSpace(obj)) {
244 MapWord map_word = obj->map_word();
245 if (map_word.IsForwardingAddress()) {
246 HeapObject* dest = map_word.ToForwardingAddress();
247 WhiteToGrey(dest, Marking::MarkBitFrom(dest));
248 *new_top++ = dest;
249 ASSERT(Color(obj) == Color(dest));
250 }
251 } else {
252 *new_top++ = obj;
253 }
254 }
255
256 marking_stack_.set_top(new_top);
257 }
258
259
207 void IncrementalMarking::Hurry() { 260 void IncrementalMarking::Hurry() {
208 if (state() == MARKING) { 261 if (state() == MARKING) {
209 double start = 0.0; 262 double start = 0.0;
210 if (FLAG_trace_incremental_marking) { 263 if (FLAG_trace_incremental_marking) {
211 PrintF("[IncrementalMarking] Hurry\n"); 264 PrintF("[IncrementalMarking] Hurry\n");
212 start = OS::TimeCurrentMillis(); 265 start = OS::TimeCurrentMillis();
213 } 266 }
214 // TODO(gc) hurry can mark objects it encounters black as mutator 267 // TODO(gc) hurry can mark objects it encounters black as mutator
215 // was stopped. 268 // was stopped.
216 Map* filler_map = Heap::one_pointer_filler_map(); 269 Map* filler_map = Heap::one_pointer_filler_map();
217 while (!marking_stack_.is_empty()) { 270 while (!marking_stack_.is_empty()) {
218 HeapObject* obj = marking_stack_.Pop(); 271 HeapObject* obj = marking_stack_.Pop();
219 272
220 // Explicitly skip one word fillers. Incremental markbit patterns are 273 // Explicitly skip one word fillers. Incremental markbit patterns are
221 // correct only for objects that occupy at least two words. 274 // correct only for objects that occupy at least two words.
222 if (obj->map() != filler_map) { 275 if (obj->map() != filler_map) {
223 obj->Iterate(&marking_visitor); 276 obj->Iterate(&marking_visitor);
224 MarkBit mark_bit = Marking::MarkBitFrom(obj); 277 MarkBit mark_bit = Marking::MarkBitFrom(obj);
225 MarkBlack(mark_bit); 278 MarkBlack(mark_bit);
226 } 279 }
227 } 280 }
228 state_ = COMPLETE; 281 state_ = COMPLETE;
229 if (FLAG_trace_incremental_marking) { 282 if (FLAG_trace_incremental_marking) {
230 double end = OS::TimeCurrentMillis(); 283 double end = OS::TimeCurrentMillis();
231 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms\n", 284 PrintF("[IncrementalMarking] Complete (hurry), "
232 static_cast<int>(end - start)); 285 "spent %d ms, %d steps took %d ms (avg %d ms)\n",
286 static_cast<int>(end - start),
287 steps_count,
288 static_cast<int>(steps_took),
289 static_cast<int>(steps_took / steps_count));
233 } 290 }
234 } 291 }
235 } 292 }
236 293
237 294
238 void IncrementalMarking::Finalize() { 295 void IncrementalMarking::Finalize() {
239 Hurry(); 296 Hurry();
240 state_ = STOPPED; 297 state_ = STOPPED;
241 PatchIncrementalMarkingRecordWriteStubs(false); 298 PatchIncrementalMarkingRecordWriteStubs(false);
242 ASSERT(marking_stack_.is_empty()); 299 ASSERT(marking_stack_.is_empty());
243 } 300 }
244 301
245 302
246 void IncrementalMarking::MarkingComplete() { 303 void IncrementalMarking::MarkingComplete() {
247 state_ = COMPLETE; 304 state_ = COMPLETE;
248 // We completed marking. 305 // We completed marking.
249 if (FLAG_trace_incremental_marking) { 306 if (FLAG_trace_incremental_marking) {
250 PrintF("[IncrementalMarking] Complete (normal)\n"); 307 PrintF("[IncrementalMarking] Complete (normal), "
308 "%d steps took %d ms (avg %d ms).\n",
309 steps_count,
310 static_cast<int>(steps_took),
311 static_cast<int>(steps_took / steps_count));
251 } 312 }
252 StackGuard::RequestGC(); 313 StackGuard::RequestGC();
253 } 314 }
254 315
255 316
256 void IncrementalMarking::Step(intptr_t allocated_bytes) { 317 void IncrementalMarking::Step(intptr_t allocated_bytes) {
257 if (state_ == MARKING) { 318 if (state_ == MARKING && Heap::gc_state() == Heap::NOT_IN_GC) {
258 allocated += allocated_bytes; 319 allocated += allocated_bytes;
259 320
260 if (allocated >= kAllocatedThreshold) { 321 if (allocated >= kAllocatedThreshold) {
322 double start = 0;
323 if (FLAG_trace_incremental_marking) start = OS::TimeCurrentMillis();
261 intptr_t bytes_to_process = allocated * kAllocationMarkingFactor; 324 intptr_t bytes_to_process = allocated * kAllocationMarkingFactor;
262 int count = 0; 325 int count = 0;
263 double start = 0;
264 if (FLAG_trace_incremental_marking) {
265 PrintF("[IncrementalMarking] Marking %d bytes\n", bytes_to_process);
266 start = OS::TimeCurrentMillis();
267 }
268 326
269 Map* filler_map = Heap::one_pointer_filler_map(); 327 Map* filler_map = Heap::one_pointer_filler_map();
270 while (!marking_stack_.is_empty() && bytes_to_process > 0) { 328 while (!marking_stack_.is_empty() && bytes_to_process > 0) {
271 HeapObject* obj = marking_stack_.Pop(); 329 HeapObject* obj = marking_stack_.Pop();
272 330
273 // Explicitly skip one word fillers. Incremental markbit patterns are 331 // Explicitly skip one word fillers. Incremental markbit patterns are
274 // correct only for objects that occupy at least two words. 332 // correct only for objects that occupy at least two words.
275 if (obj->map() != filler_map) { 333 if (obj->map() != filler_map) {
276 ASSERT(IsGrey(Marking::MarkBitFrom(obj))); 334 ASSERT(IsGrey(Marking::MarkBitFrom(obj)));
335 // TODO(gc) switch to static visitor instead of normal visitor.
277 Map* map = obj->map(); 336 Map* map = obj->map();
278 int size = obj->SizeFromMap(map); 337 int size = obj->SizeFromMap(map);
279 bytes_to_process -= size; 338 bytes_to_process -= size;
280 MarkBit map_mark_bit = Marking::MarkBitFrom(map); 339 MarkBit map_mark_bit = Marking::MarkBitFrom(map);
281 if (IsWhite(map_mark_bit)) WhiteToGrey(map, map_mark_bit); 340 if (IsWhite(map_mark_bit)) WhiteToGreyAndPush(map, map_mark_bit);
282 obj->IterateBody(map->instance_type(), size, &marking_visitor); 341 obj->IterateBody(map->instance_type(), size, &marking_visitor);
283 MarkBit obj_mark_bit = Marking::MarkBitFrom(obj); 342 MarkBit obj_mark_bit = Marking::MarkBitFrom(obj);
284 MarkBlack(obj_mark_bit); 343 MarkBlack(obj_mark_bit);
285 } 344 }
286 count++; 345 count++;
287 } 346 }
347 allocated = 0;
348 if (marking_stack_.is_empty()) MarkingComplete();
288 if (FLAG_trace_incremental_marking) { 349 if (FLAG_trace_incremental_marking) {
289 double end = OS::TimeCurrentMillis(); 350 double end = OS::TimeCurrentMillis();
290 PrintF("[IncrementalMarking] %d objects marked, spent %d ms\n", 351 steps_took += (end - start);
291 count, 352 steps_count++;
292 static_cast<int>(end - start));
293 } 353 }
294 allocated = 0;
295 if (marking_stack_.is_empty()) MarkingComplete();
296 } 354 }
297 } 355 }
298 } 356 }
299 357
300 358
301 } } // namespace v8::internal 359 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/incremental-marking.h ('k') | src/mark-compact.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698