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

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

Issue 5745005: Provide baseline GC version. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 10 years 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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 // Tell the tracer. 75 // Tell the tracer.
76 if (IsCompacting()) tracer_->set_is_compacting(); 76 if (IsCompacting()) tracer_->set_is_compacting();
77 77
78 MarkLiveObjects(); 78 MarkLiveObjects();
79 79
80 if (FLAG_collect_maps) ClearNonLiveTransitions(); 80 if (FLAG_collect_maps) ClearNonLiveTransitions();
81 81
82 SweepLargeObjectSpace(); 82 SweepLargeObjectSpace();
83 83
84 if (IsCompacting()) { 84 if (IsCompacting()) {
85 #ifndef BASELINE_GC
85 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_COMPACT); 86 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_COMPACT);
86 EncodeForwardingAddresses(); 87 EncodeForwardingAddresses();
87 88
88 Heap::MarkMapPointersAsEncoded(true); 89 Heap::MarkMapPointersAsEncoded(true);
89 UpdatePointers(); 90 UpdatePointers();
90 Heap::MarkMapPointersAsEncoded(false); 91 Heap::MarkMapPointersAsEncoded(false);
91 PcToCodeCache::FlushPcToCodeCache(); 92 PcToCodeCache::FlushPcToCodeCache();
92 93
93 RelocateObjects(); 94 RelocateObjects();
95 #else
96 UNREACHABLE();
97 #endif
94 } else { 98 } else {
95 SweepSpaces(); 99 SweepSpaces();
96 PcToCodeCache::FlushPcToCodeCache(); 100 PcToCodeCache::FlushPcToCodeCache();
97 } 101 }
98 102
99 Finish(); 103 Finish();
100 104
101 // Save the count of marked objects remaining after the collection and 105 // Save the count of marked objects remaining after the collection and
102 // null out the GC tracer. 106 // null out the GC tracer.
103 previous_marked_count_ = tracer_->marked_count(); 107 previous_marked_count_ = tracer_->marked_count();
104 ASSERT(previous_marked_count_ == 0); 108 ASSERT(previous_marked_count_ == 0);
105 tracer_ = NULL; 109 tracer_ = NULL;
106 } 110 }
107 111
108 112
109 void MarkCompactCollector::Prepare(GCTracer* tracer) { 113 void MarkCompactCollector::Prepare(GCTracer* tracer) {
114 #ifdef BASELINE_GC
115 FLAG_flush_code = false;
116 FLAG_always_compact = false;
117 FLAG_never_compact = true;
118 #endif
119
110 // Rather than passing the tracer around we stash it in a static member 120 // Rather than passing the tracer around we stash it in a static member
111 // variable. 121 // variable.
112 tracer_ = tracer; 122 tracer_ = tracer;
113 123
114 #ifdef DEBUG 124 #ifdef DEBUG
115 ASSERT(state_ == IDLE); 125 ASSERT(state_ == IDLE);
116 state_ = PREPARE_GC; 126 state_ = PREPARE_GC;
117 #endif 127 #endif
118 ASSERT(!FLAG_always_compact || !FLAG_never_compact); 128 ASSERT(!FLAG_always_compact || !FLAG_never_compact);
119 129
(...skipping 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1465 // to mark free regions larger than one word, and the size of the free 1475 // to mark free regions larger than one word, and the size of the free
1466 // region (including the first word) is written to the second word of the 1476 // region (including the first word) is written to the second word of the
1467 // region. 1477 // region.
1468 // 1478 //
1469 // Any valid map page offset must lie in the object area of the page, so map 1479 // Any valid map page offset must lie in the object area of the page, so map
1470 // page offsets less than Page::kObjectStartOffset are invalid. We use a 1480 // page offsets less than Page::kObjectStartOffset are invalid. We use a
1471 // pair of distinguished invalid map encodings (for single word and multiple 1481 // pair of distinguished invalid map encodings (for single word and multiple
1472 // words) to indicate free regions in the page found during computation of 1482 // words) to indicate free regions in the page found during computation of
1473 // forwarding addresses and skipped over in subsequent sweeps. 1483 // forwarding addresses and skipped over in subsequent sweeps.
1474 1484
1475 1485 #ifndef BASELINE_GC
1476 // Encode a free region, defined by the given start address and size, in the 1486 // Encode a free region, defined by the given start address and size, in the
1477 // first word or two of the region. 1487 // first word or two of the region.
1478 void EncodeFreeRegion(Address free_start, int free_size) { 1488 void EncodeFreeRegion(Address free_start, int free_size) {
1479 ASSERT(free_size >= kIntSize); 1489 ASSERT(free_size >= kIntSize);
1480 if (free_size == kIntSize) { 1490 if (free_size == kIntSize) {
1481 Memory::uint32_at(free_start) = MarkCompactCollector::kSingleFreeEncoding; 1491 Memory::uint32_at(free_start) = MarkCompactCollector::kSingleFreeEncoding;
1482 } else { 1492 } else {
1483 ASSERT(free_size >= 2 * kIntSize); 1493 ASSERT(free_size >= 2 * kIntSize);
1484 Memory::uint32_at(free_start) = MarkCompactCollector::kMultiFreeEncoding; 1494 Memory::uint32_at(free_start) = MarkCompactCollector::kMultiFreeEncoding;
1485 Memory::int_at(free_start + kIntSize) = free_size; 1495 Memory::int_at(free_start + kIntSize) = free_size;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 // in the page. 1692 // in the page.
1683 int offset = 0; 1693 int offset = 0;
1684 EncodeForwardingAddressesInRange<Alloc, 1694 EncodeForwardingAddressesInRange<Alloc,
1685 EncodeForwardingAddressInPagedSpace, 1695 EncodeForwardingAddressInPagedSpace,
1686 ProcessNonLive>( 1696 ProcessNonLive>(
1687 p->ObjectAreaStart(), 1697 p->ObjectAreaStart(),
1688 p->AllocationTop(), 1698 p->AllocationTop(),
1689 &offset); 1699 &offset);
1690 } 1700 }
1691 } 1701 }
1692 1702 #endif
1693 1703
1694 // We scavange new space simultaneously with sweeping. This is done in two 1704 // We scavange new space simultaneously with sweeping. This is done in two
1695 // passes. 1705 // passes.
1696 // The first pass migrates all alive objects from one semispace to another or 1706 // The first pass migrates all alive objects from one semispace to another or
1697 // promotes them to old space. Forwading address is written directly into 1707 // promotes them to old space. Forwading address is written directly into
1698 // first word of object without any encoding. If object is dead we are writing 1708 // first word of object without any encoding. If object is dead we are writing
1699 // NULL as a forwarding address. 1709 // NULL as a forwarding address.
1700 // The second pass updates pointers to new space in all spaces. It is possible 1710 // The second pass updates pointers to new space in all spaces. It is possible
1701 // to encounter pointers to dead objects during traversal of dirty regions we 1711 // to encounter pointers to dead objects during traversal of dirty regions we
1702 // should clear them to avoid encountering them during next dirty regions 1712 // should clear them to avoid encountering them during next dirty regions
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
2055 ASSERT(new_allocation_top_page == prec_first_empty_page); 2065 ASSERT(new_allocation_top_page == prec_first_empty_page);
2056 } else { 2066 } else {
2057 ASSERT(new_allocation_top_page == first_empty_page); 2067 ASSERT(new_allocation_top_page == first_empty_page);
2058 } 2068 }
2059 #endif 2069 #endif
2060 2070
2061 space->SetTop(new_allocation_top); 2071 space->SetTop(new_allocation_top);
2062 } 2072 }
2063 } 2073 }
2064 2074
2065 2075 #ifndef BASELINE_GC
2066 void MarkCompactCollector::EncodeForwardingAddresses() { 2076 void MarkCompactCollector::EncodeForwardingAddresses() {
2067 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); 2077 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
2068 // Objects in the active semispace of the young generation may be 2078 // Objects in the active semispace of the young generation may be
2069 // relocated to the inactive semispace (if not promoted). Set the 2079 // relocated to the inactive semispace (if not promoted). Set the
2070 // relocation info to the beginning of the inactive semispace. 2080 // relocation info to the beginning of the inactive semispace.
2071 Heap::new_space()->MCResetRelocationInfo(); 2081 Heap::new_space()->MCResetRelocationInfo();
2072 2082
2073 // Compute the forwarding pointers in each space. 2083 // Compute the forwarding pointers in each space.
2074 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace, 2084 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace,
2075 ReportDeleteIfNeeded>( 2085 ReportDeleteIfNeeded>(
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 return; 2320 return;
2311 2321
2312 for (HeapObject* obj = map_to_evacuate_it_.next(); 2322 for (HeapObject* obj = map_to_evacuate_it_.next();
2313 obj != NULL; obj = map_to_evacuate_it_.next()) 2323 obj != NULL; obj = map_to_evacuate_it_.next())
2314 ASSERT(FreeListNode::IsFreeListNode(obj)); 2324 ASSERT(FreeListNode::IsFreeListNode(obj));
2315 } 2325 }
2316 #endif 2326 #endif
2317 }; 2327 };
2318 2328
2319 MapCompact::MapUpdatingVisitor MapCompact::map_updating_visitor_; 2329 MapCompact::MapUpdatingVisitor MapCompact::map_updating_visitor_;
2320 2330 #endif
2321 2331
2322 void MarkCompactCollector::SweepSpaces() { 2332 void MarkCompactCollector::SweepSpaces() {
2323 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP); 2333 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP);
2324 2334
2325 ASSERT(state_ == SWEEP_SPACES); 2335 ASSERT(state_ == SWEEP_SPACES);
2326 ASSERT(!IsCompacting()); 2336 ASSERT(!IsCompacting());
2327 // Noncompacting collections simply sweep the spaces to clear the mark 2337 // Noncompacting collections simply sweep the spaces to clear the mark
2328 // bits and free the nonlive blocks (for old and map spaces). We sweep 2338 // bits and free the nonlive blocks (for old and map spaces). We sweep
2329 // the map space last because freeing non-live maps overwrites them and 2339 // the map space last because freeing non-live maps overwrites them and
2330 // the other spaces rely on possibly non-live maps to get the sizes for 2340 // the other spaces rely on possibly non-live maps to get the sizes for
2331 // non-live objects. 2341 // non-live objects.
2332 SweepSpace(Heap::old_pointer_space()); 2342 SweepSpace(Heap::old_pointer_space());
2333 SweepSpace(Heap::old_data_space()); 2343 SweepSpace(Heap::old_data_space());
2334 SweepSpace(Heap::code_space()); 2344 SweepSpace(Heap::code_space());
2335 SweepSpace(Heap::cell_space()); 2345 SweepSpace(Heap::cell_space());
2336 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE); 2346 { GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_SWEEP_NEWSPACE);
2337 SweepNewSpace(Heap::new_space()); 2347 SweepNewSpace(Heap::new_space());
2338 } 2348 }
2339 SweepSpace(Heap::map_space()); 2349 SweepSpace(Heap::map_space());
2340 2350
2341 Heap::IterateDirtyRegions(Heap::map_space(), 2351 Heap::IterateDirtyRegions(Heap::map_space(),
2342 &Heap::IteratePointersInDirtyMapsRegion, 2352 &Heap::IteratePointersInDirtyMapsRegion,
2343 &UpdatePointerToNewGen, 2353 &UpdatePointerToNewGen,
2344 Heap::WATERMARK_SHOULD_BE_VALID); 2354 Heap::WATERMARK_SHOULD_BE_VALID);
2345 2355
2346 intptr_t live_maps_size = Heap::map_space()->Size(); 2356 intptr_t live_maps_size = Heap::map_space()->Size();
2347 int live_maps = static_cast<int>(live_maps_size / Map::kSize); 2357 int live_maps = static_cast<int>(live_maps_size / Map::kSize);
2348 ASSERT(live_map_objects_size_ == live_maps_size); 2358 ASSERT(live_map_objects_size_ == live_maps_size);
2349 2359
2360 #ifndef BASELINE_GC
2350 if (Heap::map_space()->NeedsCompaction(live_maps)) { 2361 if (Heap::map_space()->NeedsCompaction(live_maps)) {
2351 MapCompact map_compact(live_maps); 2362 MapCompact map_compact(live_maps);
2352 2363
2353 map_compact.CompactMaps(); 2364 map_compact.CompactMaps();
2354 map_compact.UpdateMapPointersInRoots(); 2365 map_compact.UpdateMapPointersInRoots();
2355 2366
2356 PagedSpaces spaces; 2367 PagedSpaces spaces;
2357 for (PagedSpace* space = spaces.next(); 2368 for (PagedSpace* space = spaces.next();
2358 space != NULL; space = spaces.next()) { 2369 space != NULL; space = spaces.next()) {
2359 if (space == Heap::map_space()) continue; 2370 if (space == Heap::map_space()) continue;
2360 map_compact.UpdateMapPointersInPagedSpace(space); 2371 map_compact.UpdateMapPointersInPagedSpace(space);
2361 } 2372 }
2362 map_compact.UpdateMapPointersInNewSpace(); 2373 map_compact.UpdateMapPointersInNewSpace();
2363 map_compact.UpdateMapPointersInLargeObjectSpace(); 2374 map_compact.UpdateMapPointersInLargeObjectSpace();
2364 2375
2365 map_compact.Finish(); 2376 map_compact.Finish();
2366 } 2377 }
2378 #else
2379 USE(live_maps);
2380 #endif
2367 } 2381 }
2368 2382
2369 2383
2370 // Iterate the live objects in a range of addresses (eg, a page or a 2384 // Iterate the live objects in a range of addresses (eg, a page or a
2371 // semispace). The live regions of the range have been linked into a list. 2385 // semispace). The live regions of the range have been linked into a list.
2372 // The first live region is [first_live_start, first_live_end), and the last 2386 // The first live region is [first_live_start, first_live_end), and the last
2373 // address in the range is top. The callback function is used to get the 2387 // address in the range is top. The callback function is used to get the
2374 // size of each live object. 2388 // size of each live object.
2375 int MarkCompactCollector::IterateLiveObjectsInRange( 2389 int MarkCompactCollector::IterateLiveObjectsInRange(
2376 Address start, 2390 Address start,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 while (it.has_next()) { 2423 while (it.has_next()) {
2410 Page* p = it.next(); 2424 Page* p = it.next();
2411 total += IterateLiveObjectsInRange(p->ObjectAreaStart(), 2425 total += IterateLiveObjectsInRange(p->ObjectAreaStart(),
2412 p->AllocationTop(), 2426 p->AllocationTop(),
2413 size_f); 2427 size_f);
2414 } 2428 }
2415 return total; 2429 return total;
2416 } 2430 }
2417 2431
2418 2432
2433 #ifndef BASELINE_GC
2419 // ------------------------------------------------------------------------- 2434 // -------------------------------------------------------------------------
2420 // Phase 3: Update pointers 2435 // Phase 3: Update pointers
2421 2436
2422 // Helper class for updating pointers in HeapObjects. 2437 // Helper class for updating pointers in HeapObjects.
2423 class UpdatingVisitor: public ObjectVisitor { 2438 class UpdatingVisitor: public ObjectVisitor {
2424 public: 2439 public:
2425 void VisitPointer(Object** p) { 2440 void VisitPointer(Object** p) {
2426 UpdatePointer(p); 2441 UpdatePointer(p);
2427 } 2442 }
2428 2443
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
2891 2906
2892 HeapObject* copied_to = HeapObject::FromAddress(new_addr); 2907 HeapObject* copied_to = HeapObject::FromAddress(new_addr);
2893 if (copied_to->IsJSFunction()) { 2908 if (copied_to->IsJSFunction()) {
2894 PROFILE(FunctionMoveEvent(old_addr, new_addr)); 2909 PROFILE(FunctionMoveEvent(old_addr, new_addr));
2895 PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to))); 2910 PROFILE(FunctionCreateEventFromMove(JSFunction::cast(copied_to)));
2896 } 2911 }
2897 HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr)); 2912 HEAP_PROFILE(ObjectMoveEvent(old_addr, new_addr));
2898 2913
2899 return obj_size; 2914 return obj_size;
2900 } 2915 }
2916 #endif
2901 2917
2902 2918
2903 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) { 2919 void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) {
2904 #ifdef ENABLE_LOGGING_AND_PROFILING 2920 #ifdef ENABLE_LOGGING_AND_PROFILING
2905 if (obj->IsCode()) { 2921 if (obj->IsCode()) {
2906 PROFILE(CodeDeleteEvent(obj->address())); 2922 PROFILE(CodeDeleteEvent(obj->address()));
2907 } else if (obj->IsJSFunction()) { 2923 } else if (obj->IsJSFunction()) {
2908 PROFILE(FunctionDeleteEvent(obj->address())); 2924 PROFILE(FunctionDeleteEvent(obj->address()));
2909 } 2925 }
2910 #endif 2926 #endif
2911 } 2927 }
2912 2928
2913 2929
2914 int MarkCompactCollector::SizeOfMarkedObject(HeapObject* obj) { 2930 int MarkCompactCollector::SizeOfMarkedObject(HeapObject* obj) {
2915 MapWord map_word = obj->map_word(); 2931 MapWord map_word = obj->map_word();
2916 map_word.ClearMark(); 2932 map_word.ClearMark();
2917 return obj->SizeFromMap(map_word.ToMap()); 2933 return obj->SizeFromMap(map_word.ToMap());
2918 } 2934 }
2919 2935
2920 2936
2921 void MarkCompactCollector::Initialize() { 2937 void MarkCompactCollector::Initialize() {
2922 StaticPointersToNewGenUpdatingVisitor::Initialize(); 2938 StaticPointersToNewGenUpdatingVisitor::Initialize();
2923 StaticMarkingVisitor::Initialize(); 2939 StaticMarkingVisitor::Initialize();
2924 } 2940 }
2925 2941
2926 2942
2927 } } // namespace v8::internal 2943 } } // namespace v8::internal
OLDNEW
« src/ia32/codegen-ia32.cc ('K') | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698