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

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

Issue 6928010: Make the marking stack into a deque (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 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 | Annotate | Revision Log
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 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 CodeStub::RecordWrite) { 205 CodeStub::RecordWrite) {
206 Object* e = stubs->ValueAt(i); 206 Object* e = stubs->ValueAt(i);
207 if (e->IsCode()) { 207 if (e->IsCode()) {
208 RecordWriteStub::Patch(Code::cast(e), enable); 208 RecordWriteStub::Patch(Code::cast(e), enable);
209 } 209 }
210 } 210 }
211 } 211 }
212 } 212 }
213 } 213 }
214 214
215 static VirtualMemory* marking_stack_memory = NULL; 215 static VirtualMemory* marking_deque_memory = NULL;
216 216
217 static void EnsureMarkingStackIsCommitted() { 217 static void EnsureMarkingDequeIsCommitted() {
218 if (marking_stack_memory == NULL) { 218 if (marking_deque_memory == NULL) {
219 marking_stack_memory = new VirtualMemory(4*MB); 219 marking_deque_memory = new VirtualMemory(4*MB);
220 marking_stack_memory->Commit( 220 marking_deque_memory->Commit(
221 reinterpret_cast<Address>(marking_stack_memory->address()), 221 reinterpret_cast<Address>(marking_deque_memory->address()),
222 marking_stack_memory->size(), 222 marking_deque_memory->size(),
223 false); // Not executable. 223 false); // Not executable.
224 } 224 }
225 } 225 }
226 226
227 227
228 void IncrementalMarking::Start() { 228 void IncrementalMarking::Start() {
229 if (FLAG_trace_incremental_marking) { 229 if (FLAG_trace_incremental_marking) {
230 PrintF("[IncrementalMarking] Start\n"); 230 PrintF("[IncrementalMarking] Start\n");
231 } 231 }
232 ASSERT(FLAG_incremental_marking); 232 ASSERT(FLAG_incremental_marking);
233 ASSERT(state_ == STOPPED); 233 ASSERT(state_ == STOPPED);
234 state_ = MARKING; 234 state_ = MARKING;
235 235
236 ResetStepCounters(); 236 ResetStepCounters();
237 237
238 PatchIncrementalMarkingRecordWriteStubs(true); 238 PatchIncrementalMarkingRecordWriteStubs(true);
239 239
240 EnsureMarkingStackIsCommitted(); 240 EnsureMarkingDequeIsCommitted();
241 241
242 // Initialize marking stack. 242 // Initialize marking stack.
243 Address addr = static_cast<Address>(marking_stack_memory->address()); 243 Address addr = static_cast<Address>(marking_deque_memory->address());
244 marking_stack_.Initialize(addr, 244 marking_deque_.Initialize(addr,
245 addr + marking_stack_memory->size()); 245 addr + marking_deque_memory->size());
246 246
247 // Clear markbits. 247 // Clear markbits.
248 Address new_space_low = heap_->new_space()->ToSpaceLow(); 248 Address new_space_low = heap_->new_space()->ToSpaceLow();
249 Address new_space_high = heap_->new_space()->ToSpaceHigh(); 249 Address new_space_high = heap_->new_space()->ToSpaceHigh();
250 heap_->marking()->ClearRange( 250 heap_->marking()->ClearRange(
251 new_space_low, static_cast<int>(new_space_high - new_space_low)); 251 new_space_low, static_cast<int>(new_space_high - new_space_low));
252 252
253 ClearMarkbits(); 253 ClearMarkbits();
254 254
255 #ifdef DEBUG 255 #ifdef DEBUG
(...skipping 16 matching lines...) Expand all
272 void IncrementalMarking::PrepareForScavenge() { 272 void IncrementalMarking::PrepareForScavenge() {
273 if (IsStopped()) return; 273 if (IsStopped()) return;
274 274
275 Address new_space_low = heap_->new_space()->FromSpaceLow(); 275 Address new_space_low = heap_->new_space()->FromSpaceLow();
276 Address new_space_high = heap_->new_space()->FromSpaceHigh(); 276 Address new_space_high = heap_->new_space()->FromSpaceHigh();
277 heap_->marking()->ClearRange( 277 heap_->marking()->ClearRange(
278 new_space_low, static_cast<int>(new_space_high - new_space_low)); 278 new_space_low, static_cast<int>(new_space_high - new_space_low));
279 } 279 }
280 280
281 281
282 void IncrementalMarking::UpdateMarkingStackAfterScavenge() { 282 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
283 if (IsStopped()) return; 283 if (IsStopped()) return;
284 284
285 HeapObject** current = marking_stack_.low(); 285 intptr_t current = marking_deque_.bottom();
286 HeapObject** top = marking_stack_.top(); 286 intptr_t mask = marking_deque_.mask();
287 HeapObject** new_top = current; 287 intptr_t limit = marking_deque_.top();
288 HeapObject** array = marking_deque_.array();
289 intptr_t new_top = current;
288 290
289 while (current < top) { 291 while (current != limit) {
290 HeapObject* obj = *current++; 292 HeapObject* obj = array[current];
293 current = ((current + 1) & mask);
291 if (heap_->InNewSpace(obj)) { 294 if (heap_->InNewSpace(obj)) {
292 MapWord map_word = obj->map_word(); 295 MapWord map_word = obj->map_word();
293 if (map_word.IsForwardingAddress()) { 296 if (map_word.IsForwardingAddress()) {
294 HeapObject* dest = map_word.ToForwardingAddress(); 297 HeapObject* dest = map_word.ToForwardingAddress();
295 WhiteToGrey(dest, heap_->marking()->MarkBitFrom(dest)); 298 WhiteToGrey(dest, heap_->marking()->MarkBitFrom(dest));
296 *new_top++ = dest; 299 array[new_top] = dest;
300 new_top = ((new_top + 1) & mask);
297 ASSERT(Color(obj) == Color(dest)); 301 ASSERT(Color(obj) == Color(dest));
298 } 302 }
299 } else { 303 } else {
300 *new_top++ = obj; 304 array[new_top] = obj;
305 new_top = ((new_top + 1) & mask);
301 } 306 }
302 } 307 }
303 308
304 marking_stack_.set_top(new_top); 309 marking_deque_.set_top(new_top);
305 } 310 }
306 311
307 312
308 void IncrementalMarking::Hurry() { 313 void IncrementalMarking::Hurry() {
309 if (state() == MARKING) { 314 if (state() == MARKING) {
310 double start = 0.0; 315 double start = 0.0;
311 if (FLAG_trace_incremental_marking) { 316 if (FLAG_trace_incremental_marking) {
312 PrintF("[IncrementalMarking] Hurry\n"); 317 PrintF("[IncrementalMarking] Hurry\n");
313 start = OS::TimeCurrentMillis(); 318 start = OS::TimeCurrentMillis();
314 } 319 }
315 // TODO(gc) hurry can mark objects it encounters black as mutator 320 // TODO(gc) hurry can mark objects it encounters black as mutator
316 // was stopped. 321 // was stopped.
317 Map* filler_map = heap_->one_pointer_filler_map(); 322 Map* filler_map = heap_->one_pointer_filler_map();
318 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this); 323 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
319 while (!marking_stack_.is_empty()) { 324 while (!marking_deque_.IsEmpty()) {
320 HeapObject* obj = marking_stack_.Pop(); 325 HeapObject* obj = marking_deque_.Pop();
321 326
322 // Explicitly skip one word fillers. Incremental markbit patterns are 327 // Explicitly skip one word fillers. Incremental markbit patterns are
323 // correct only for objects that occupy at least two words. 328 // correct only for objects that occupy at least two words.
324 if (obj->map() != filler_map) { 329 if (obj->map() != filler_map) {
325 obj->Iterate(&marking_visitor); 330 obj->Iterate(&marking_visitor);
326 MarkBit mark_bit = heap_->marking()->MarkBitFrom(obj); 331 MarkBit mark_bit = heap_->marking()->MarkBitFrom(obj);
327 MarkBlack(mark_bit); 332 MarkBlack(mark_bit);
328 } 333 }
329 } 334 }
330 state_ = COMPLETE; 335 state_ = COMPLETE;
331 if (FLAG_trace_incremental_marking) { 336 if (FLAG_trace_incremental_marking) {
332 double end = OS::TimeCurrentMillis(); 337 double end = OS::TimeCurrentMillis();
333 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n", 338 PrintF("[IncrementalMarking] Complete (hurry), spent %d ms.\n",
334 static_cast<int>(end - start)); 339 static_cast<int>(end - start));
335 } 340 }
336 } 341 }
337 } 342 }
338 343
339 344
340 void IncrementalMarking::Finalize() { 345 void IncrementalMarking::Finalize() {
341 Hurry(); 346 Hurry();
342 state_ = STOPPED; 347 state_ = STOPPED;
343 heap_->new_space()->LowerInlineAllocationLimit(0); 348 heap_->new_space()->LowerInlineAllocationLimit(0);
344 IncrementalMarking::set_should_hurry(false); 349 IncrementalMarking::set_should_hurry(false);
345 ResetStepCounters(); 350 ResetStepCounters();
346 PatchIncrementalMarkingRecordWriteStubs(false); 351 PatchIncrementalMarkingRecordWriteStubs(false);
347 ASSERT(marking_stack_.is_empty()); 352 ASSERT(marking_deque_.IsEmpty());
348 ISOLATE->stack_guard()->Continue(GC_REQUEST); 353 ISOLATE->stack_guard()->Continue(GC_REQUEST);
349 } 354 }
350 355
351 356
352 void IncrementalMarking::MarkingComplete() { 357 void IncrementalMarking::MarkingComplete() {
353 state_ = COMPLETE; 358 state_ = COMPLETE;
354 // We will set the stack guard to request a GC now. This will mean the rest 359 // We will set the stack guard to request a GC now. This will mean the rest
355 // of the GC gets performed as soon as possible (we can't do a GC here in a 360 // of the GC gets performed as soon as possible (we can't do a GC here in a
356 // record-write context). If a few things get allocated between now and then 361 // record-write context). If a few things get allocated between now and then
357 // that shouldn't make us do a scavenge and keep being incremental, so we set 362 // that shouldn't make us do a scavenge and keep being incremental, so we set
(...skipping 19 matching lines...) Expand all
377 if (FLAG_trace_incremental_marking || FLAG_trace_gc) { 382 if (FLAG_trace_incremental_marking || FLAG_trace_gc) {
378 start = OS::TimeCurrentMillis(); 383 start = OS::TimeCurrentMillis();
379 } 384 }
380 385
381 intptr_t bytes_to_process = allocated_ * allocation_marking_factor_; 386 intptr_t bytes_to_process = allocated_ * allocation_marking_factor_;
382 int count = 0; 387 int count = 0;
383 388
384 Map* filler_map = heap_->one_pointer_filler_map(); 389 Map* filler_map = heap_->one_pointer_filler_map();
385 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this); 390 IncrementalMarkingMarkingVisitor marking_visitor(heap_, this);
386 Marking* marking = heap_->marking(); 391 Marking* marking = heap_->marking();
387 while (!marking_stack_.is_empty() && bytes_to_process > 0) { 392 while (!marking_deque_.IsEmpty() && bytes_to_process > 0) {
388 HeapObject* obj = marking_stack_.Pop(); 393 HeapObject* obj = marking_deque_.Pop();
389 394
390 // Explicitly skip one word fillers. Incremental markbit patterns are 395 // Explicitly skip one word fillers. Incremental markbit patterns are
391 // correct only for objects that occupy at least two words. 396 // correct only for objects that occupy at least two words.
392 Map* map = obj->map(); 397 Map* map = obj->map();
393 if (map != filler_map) { 398 if (map != filler_map) {
394 ASSERT(IsGrey(marking->MarkBitFrom(obj))); 399 ASSERT(IsGrey(marking->MarkBitFrom(obj)));
395 int size = obj->SizeFromMap(map); 400 int size = obj->SizeFromMap(map);
396 bytes_to_process -= size; 401 bytes_to_process -= size;
397 MarkBit map_mark_bit = marking->MarkBitFromOldSpace(map); 402 MarkBit map_mark_bit = marking->MarkBitFromOldSpace(map);
398 if (IsWhite(map_mark_bit)) WhiteToGreyAndPush(map, map_mark_bit); 403 if (IsWhite(map_mark_bit)) WhiteToGreyAndPush(map, map_mark_bit);
399 // TODO(gc) switch to static visitor instead of normal visitor. 404 // TODO(gc) switch to static visitor instead of normal visitor.
400 obj->IterateBody(map->instance_type(), size, &marking_visitor); 405 obj->IterateBody(map->instance_type(), size, &marking_visitor);
401 MarkBit obj_mark_bit = marking->MarkBitFrom(obj); 406 MarkBit obj_mark_bit = marking->MarkBitFrom(obj);
402 MarkBlack(obj_mark_bit); 407 MarkBlack(obj_mark_bit);
403 } 408 }
404 count++; 409 count++;
405 } 410 }
406 allocated_ = 0; 411 allocated_ = 0;
407 if (marking_stack_.is_empty()) MarkingComplete(); 412 if (marking_deque_.IsEmpty()) MarkingComplete();
408 if (FLAG_trace_incremental_marking || FLAG_trace_gc) { 413 if (FLAG_trace_incremental_marking || FLAG_trace_gc) {
409 double end = OS::TimeCurrentMillis(); 414 double end = OS::TimeCurrentMillis();
410 steps_took_ += (end - start); 415 steps_took_ += (end - start);
411 } 416 }
412 417
413 steps_count_++; 418 steps_count_++;
414 419
415 if ((steps_count_ % kAllocationMarkingFactorSpeedupInterval) == 0) { 420 if ((steps_count_ % kAllocationMarkingFactorSpeedupInterval) == 0) {
416 allocation_marking_factor_ += kAllocationMarkingFactorSpeedup; 421 allocation_marking_factor_ += kAllocationMarkingFactorSpeedup;
417 allocation_marking_factor_ *= 1.3; 422 allocation_marking_factor_ *= 1.3;
418 if (FLAG_trace_gc) { 423 if (FLAG_trace_gc) {
419 PrintF("Marking speed increased to %d\n", allocation_marking_factor_); 424 PrintF("Marking speed increased to %d\n", allocation_marking_factor_);
420 } 425 }
421 } 426 }
422 } 427 }
423 } 428 }
424 } 429 }
425 430
426 431
427 } } // namespace v8::internal 432 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/incremental-marking.h ('k') | src/incremental-marking-inl.h » ('j') | src/mark-compact.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698