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

Side by Side Diff: src/mark-compact.cc

Issue 7247002: Estimate a (close) upper bound on the size of black-marked objects on each page. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Address review comments. Make compile on x64. Created 9 years, 5 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/mark-compact.h ('k') | src/mark-compact-inl.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 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 VerifyMarkbitsAreClean(heap->map_space()); 278 VerifyMarkbitsAreClean(heap->map_space());
279 VerifyMarkbitsAreClean(heap->new_space()); 279 VerifyMarkbitsAreClean(heap->new_space());
280 } 280 }
281 #endif 281 #endif
282 282
283 283
284 static void ClearMarkbits(PagedSpace* space) { 284 static void ClearMarkbits(PagedSpace* space) {
285 PageIterator it(space); 285 PageIterator it(space);
286 286
287 while (it.has_next()) { 287 while (it.has_next()) {
288 Page* p = it.next(); 288 Bitmap::Clear(it.next());
289 p->markbits()->Clear();
290 } 289 }
291 } 290 }
292 291
293 292
294 static void ClearMarkbits(NewSpace* space) { 293 static void ClearMarkbits(NewSpace* space) {
295 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd()); 294 NewSpacePageIterator it(space->ToSpaceStart(), space->ToSpaceEnd());
296 295
297 while (it.has_next()) { 296 while (it.has_next()) {
298 NewSpacePage* p = it.next(); 297 Bitmap::Clear(it.next());
299 p->markbits()->Clear();
300 } 298 }
301 } 299 }
302 300
303 301
304 static void ClearMarkbits(Heap* heap) { 302 static void ClearMarkbits(Heap* heap) {
305 // TODO(gc): Clean the mark bits while sweeping. 303 // TODO(gc): Clean the mark bits while sweeping.
306 ClearMarkbits(heap->code_space()); 304 ClearMarkbits(heap->code_space());
307 ClearMarkbits(heap->map_space()); 305 ClearMarkbits(heap->map_space());
308 ClearMarkbits(heap->old_pointer_space()); 306 ClearMarkbits(heap->old_pointer_space());
309 ClearMarkbits(heap->old_data_space()); 307 ClearMarkbits(heap->old_data_space());
310 ClearMarkbits(heap->cell_space()); 308 ClearMarkbits(heap->cell_space());
311 ClearMarkbits(heap->new_space()); 309 ClearMarkbits(heap->new_space());
312 } 310 }
313 311
314 312
315 void Marking::TransferMark(Address old_start, Address new_start) { 313 bool Marking::TransferMark(Address old_start, Address new_start) {
316 if (old_start == new_start) return; 314 // This is only used when resizing an object.
315 ASSERT(MemoryChunk::FromAddress(old_start) ==
316 MemoryChunk::FromAddress(new_start));
317 // If the mark doesn't move, we don't check the color of the object.
318 // It doesn't matter whether the object is black, since it hasn't changed
319 // size, so the adjustment to the live data count will be zero anyway.
320 if (old_start == new_start) return false;
317 321
318 MarkBit new_mark_bit = MarkBitFrom(new_start); 322 MarkBit new_mark_bit = MarkBitFrom(new_start);
319 323
320 if (heap_->incremental_marking()->IsMarking()) { 324 if (heap_->incremental_marking()->IsMarking()) {
321 MarkBit old_mark_bit = MarkBitFrom(old_start); 325 MarkBit old_mark_bit = MarkBitFrom(old_start);
322 #ifdef DEBUG 326 #ifdef DEBUG
323 ObjectColor old_color = Color(old_mark_bit); 327 ObjectColor old_color = Color(old_mark_bit);
324 #endif 328 #endif
325 if (Marking::IsBlack(old_mark_bit)) { 329 if (Marking::IsBlack(old_mark_bit)) {
326 Marking::MarkBlack(new_mark_bit); 330 Marking::MarkBlack(new_mark_bit);
327 old_mark_bit.Clear(); 331 old_mark_bit.Clear();
332 return true;
328 } else if (Marking::IsGrey(old_mark_bit)) { 333 } else if (Marking::IsGrey(old_mark_bit)) {
329 old_mark_bit.Next().Clear(); 334 old_mark_bit.Next().Clear();
330 heap_->incremental_marking()->WhiteToGreyAndPush( 335 heap_->incremental_marking()->WhiteToGreyAndPush(
331 HeapObject::FromAddress(new_start), new_mark_bit); 336 HeapObject::FromAddress(new_start), new_mark_bit);
332 heap_->incremental_marking()->RestartIfNotMarking(); 337 heap_->incremental_marking()->RestartIfNotMarking();
333 // TODO(gc): if we shift huge array in the loop we might end up pushing 338 // TODO(gc): if we shift huge array in the loop we might end up pushing
334 // too much into the marking deque. Maybe we should check one or two 339 // too much into the marking deque. Maybe we should check one or two
335 // elements on top/bottom of the marking deque to see whether they are 340 // elements on top/bottom of the marking deque to see whether they are
336 // equal to old_start. 341 // equal to old_start.
337 } 342 }
338 343
339 #ifdef DEBUG 344 #ifdef DEBUG
340 ObjectColor new_color = Color(new_mark_bit); 345 ObjectColor new_color = Color(new_mark_bit);
341 ASSERT(new_color == old_color); 346 ASSERT(new_color == old_color);
342 #endif 347 #endif
343 } else { 348 return false;
344 if (heap_->InNewSpace(old_start)) {
345 return;
346 } else {
347 MarkBit old_mark_bit = MarkBitFrom(old_start);
348 if (!old_mark_bit.Get()) {
349 return;
350 }
351 }
352 new_mark_bit.Set();
353 } 349 }
350 MarkBit old_mark_bit = MarkBitFrom(old_start);
351 if (!old_mark_bit.Get()) {
352 return false;
353 }
354 new_mark_bit.Set();
355 return true;
354 } 356 }
355 357
356 358
357 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) { 359 void MarkCompactCollector::CollectEvacuationCandidates(PagedSpace* space) {
358 ASSERT(space->identity() == OLD_POINTER_SPACE || 360 ASSERT(space->identity() == OLD_POINTER_SPACE ||
359 space->identity() == OLD_DATA_SPACE); 361 space->identity() == OLD_DATA_SPACE);
360 362
361 PageIterator it(space); 363 PageIterator it(space);
362 while (it.has_next()) { 364 while (it.has_next()) {
363 Page* p = it.next(); 365 Page* p = it.next();
(...skipping 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after
1373 } 1375 }
1374 } 1376 }
1375 1377
1376 1378
1377 void MarkCompactCollector::MarkMapContents(Map* map) { 1379 void MarkCompactCollector::MarkMapContents(Map* map) {
1378 // Mark prototype transitions array but don't push it into marking stack. 1380 // Mark prototype transitions array but don't push it into marking stack.
1379 // This will make references from it weak. We will clean dead prototype 1381 // This will make references from it weak. We will clean dead prototype
1380 // transitions in ClearNonLiveTransitions. 1382 // transitions in ClearNonLiveTransitions.
1381 FixedArray* prototype_transitions = map->prototype_transitions(); 1383 FixedArray* prototype_transitions = map->prototype_transitions();
1382 MarkBit mark = Marking::MarkBitFrom(prototype_transitions); 1384 MarkBit mark = Marking::MarkBitFrom(prototype_transitions);
1383 if (!mark.Get()) mark.Set(); 1385 if (!mark.Get()) {
1386 mark.Set();
1387 MemoryChunk::IncrementLiveBytes(prototype_transitions->address(),
1388 prototype_transitions->Size());
1389 }
1384 1390
1385 Object** raw_descriptor_array_slot = 1391 Object** raw_descriptor_array_slot =
1386 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset); 1392 HeapObject::RawField(map, Map::kInstanceDescriptorsOrBitField3Offset);
1387 Object* raw_descriptor_array = *raw_descriptor_array_slot; 1393 Object* raw_descriptor_array = *raw_descriptor_array_slot;
1388 if (!raw_descriptor_array->IsSmi()) { 1394 if (!raw_descriptor_array->IsSmi()) {
1389 MarkDescriptorArray( 1395 MarkDescriptorArray(
1390 reinterpret_cast<DescriptorArray*>(raw_descriptor_array)); 1396 reinterpret_cast<DescriptorArray*>(raw_descriptor_array));
1391 } 1397 }
1392 1398
1393 // Mark the Object* fields of the Map. 1399 // Mark the Object* fields of the Map.
(...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 // migrate live objects and write forwarding addresses. This stage puts 2217 // migrate live objects and write forwarding addresses. This stage puts
2212 // new entries in the store buffer and may cause some pages to be marked 2218 // new entries in the store buffer and may cause some pages to be marked
2213 // scan-on-scavenge. 2219 // scan-on-scavenge.
2214 SemiSpaceIterator from_it(from_bottom, from_top); 2220 SemiSpaceIterator from_it(from_bottom, from_top);
2215 for (HeapObject* object = from_it.Next(); 2221 for (HeapObject* object = from_it.Next();
2216 object != NULL; 2222 object != NULL;
2217 object = from_it.Next()) { 2223 object = from_it.Next()) {
2218 MarkBit mark_bit = Marking::MarkBitFrom(object); 2224 MarkBit mark_bit = Marking::MarkBitFrom(object);
2219 if (mark_bit.Get()) { 2225 if (mark_bit.Get()) {
2220 mark_bit.Clear(); 2226 mark_bit.Clear();
2221
2222 int size = object->Size(); 2227 int size = object->Size();
2223 survivors_size += size; 2228 survivors_size += size;
2229 MemoryChunk::IncrementLiveBytes(object->address(), -size);
2224 2230
2225 // Aggressively promote young survivors to the old space. 2231 // Aggressively promote young survivors to the old space.
2226 if (TryPromoteObject(object, size)) { 2232 if (TryPromoteObject(object, size)) {
2227 continue; 2233 continue;
2228 } 2234 }
2229 2235
2230 // Promotion failed. Just migrate object to another semispace. 2236 // Promotion failed. Just migrate object to another semispace.
2231 MaybeObject* allocation = new_space->AllocateRaw(size); 2237 MaybeObject* allocation = new_space->AllocateRaw(size);
2232 if (allocation->IsFailure()) { 2238 if (allocation->IsFailure()) {
2233 if (!new_space->AddFreshPage()) { 2239 if (!new_space->AddFreshPage()) {
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
3073 visitor->VisitPointer(last_buffer[slot_idx]); 3079 visitor->VisitPointer(last_buffer[slot_idx]);
3074 } 3080 }
3075 } 3081 }
3076 3082
3077 3083
3078 void SlotsBuffer::Report() { 3084 void SlotsBuffer::Report() {
3079 } 3085 }
3080 3086
3081 3087
3082 } } // namespace v8::internal 3088 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/mark-compact-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698