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

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

Issue 16286018: Prevent excessive processing of weak maps while marking. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Hannes Payer. Created 7 years, 6 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2056 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 ref_groups->Rewind(last); 2067 ref_groups->Rewind(last);
2068 } 2068 }
2069 2069
2070 2070
2071 // Mark all objects reachable from the objects on the marking stack. 2071 // Mark all objects reachable from the objects on the marking stack.
2072 // Before: the marking stack contains zero or more heap object pointers. 2072 // Before: the marking stack contains zero or more heap object pointers.
2073 // After: the marking stack is empty, and all objects reachable from the 2073 // After: the marking stack is empty, and all objects reachable from the
2074 // marking stack have been marked, or are overflowed in the heap. 2074 // marking stack have been marked, or are overflowed in the heap.
2075 void MarkCompactCollector::EmptyMarkingDeque() { 2075 void MarkCompactCollector::EmptyMarkingDeque() {
2076 while (!marking_deque_.IsEmpty()) { 2076 while (!marking_deque_.IsEmpty()) {
2077 while (!marking_deque_.IsEmpty()) { 2077 HeapObject* object = marking_deque_.Pop();
2078 HeapObject* object = marking_deque_.Pop(); 2078 ASSERT(object->IsHeapObject());
2079 ASSERT(object->IsHeapObject()); 2079 ASSERT(heap()->Contains(object));
2080 ASSERT(heap()->Contains(object)); 2080 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object)));
2081 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object)));
2082 2081
2083 Map* map = object->map(); 2082 Map* map = object->map();
2084 MarkBit map_mark = Marking::MarkBitFrom(map); 2083 MarkBit map_mark = Marking::MarkBitFrom(map);
2085 MarkObject(map, map_mark); 2084 MarkObject(map, map_mark);
2086 2085
2087 MarkCompactMarkingVisitor::IterateBody(map, object); 2086 MarkCompactMarkingVisitor::IterateBody(map, object);
2088 }
2089
2090 // Process encountered weak maps, mark objects only reachable by those
2091 // weak maps and repeat until fix-point is reached.
2092 ProcessWeakMaps();
2093 } 2087 }
2094 } 2088 }
2095 2089
2096 2090
2097 // Sweep the heap for overflowed objects, clear their overflow bits, and 2091 // Sweep the heap for overflowed objects, clear their overflow bits, and
2098 // push them on the marking stack. Stop early if the marking stack fills 2092 // push them on the marking stack. Stop early if the marking stack fills
2099 // before sweeping completes. If sweeping completes, there are no remaining 2093 // before sweeping completes. If sweeping completes, there are no remaining
2100 // overflowed objects in the heap so the overflow flag on the markings stack 2094 // overflowed objects in the heap so the overflow flag on the markings stack
2101 // is cleared. 2095 // is cleared.
2102 void MarkCompactCollector::RefillMarkingDeque() { 2096 void MarkCompactCollector::RefillMarkingDeque() {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2147 // objects in the heap. 2141 // objects in the heap.
2148 void MarkCompactCollector::ProcessMarkingDeque() { 2142 void MarkCompactCollector::ProcessMarkingDeque() {
2149 EmptyMarkingDeque(); 2143 EmptyMarkingDeque();
2150 while (marking_deque_.overflowed()) { 2144 while (marking_deque_.overflowed()) {
2151 RefillMarkingDeque(); 2145 RefillMarkingDeque();
2152 EmptyMarkingDeque(); 2146 EmptyMarkingDeque();
2153 } 2147 }
2154 } 2148 }
2155 2149
2156 2150
2157 void MarkCompactCollector::ProcessExternalMarking(RootMarkingVisitor* visitor) { 2151 // Mark all objects reachable (transitively) from objects on the marking
2152 // stack including references only considered in the atomic marking pause.
2153 void MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) {
2158 bool work_to_do = true; 2154 bool work_to_do = true;
2159 ASSERT(marking_deque_.IsEmpty()); 2155 ASSERT(marking_deque_.IsEmpty());
2160 while (work_to_do) { 2156 while (work_to_do) {
2161 isolate()->global_handles()->IterateObjectGroups( 2157 isolate()->global_handles()->IterateObjectGroups(
2162 visitor, &IsUnmarkedHeapObjectWithHeap); 2158 visitor, &IsUnmarkedHeapObjectWithHeap);
2163 MarkImplicitRefGroups(); 2159 MarkImplicitRefGroups();
2160 ProcessWeakMaps();
2164 work_to_do = !marking_deque_.IsEmpty(); 2161 work_to_do = !marking_deque_.IsEmpty();
2165 ProcessMarkingDeque(); 2162 ProcessMarkingDeque();
2166 } 2163 }
2167 } 2164 }
2168 2165
2169 2166
2170 void MarkCompactCollector::MarkLiveObjects() { 2167 void MarkCompactCollector::MarkLiveObjects() {
2171 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); 2168 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK);
2172 // The recursive GC marker detects when it is nearing stack overflow, 2169 // The recursive GC marker detects when it is nearing stack overflow,
2173 // and switches to a different marking system. JS interrupts interfere 2170 // and switches to a different marking system. JS interrupts interfere
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2230 } 2227 }
2231 } 2228 }
2232 } 2229 }
2233 } 2230 }
2234 2231
2235 RootMarkingVisitor root_visitor(heap()); 2232 RootMarkingVisitor root_visitor(heap());
2236 MarkRoots(&root_visitor); 2233 MarkRoots(&root_visitor);
2237 2234
2238 // The objects reachable from the roots are marked, yet unreachable 2235 // The objects reachable from the roots are marked, yet unreachable
2239 // objects are unmarked. Mark objects reachable due to host 2236 // objects are unmarked. Mark objects reachable due to host
2240 // application specific logic. 2237 // application specific logic or through Harmony weak maps.
2241 ProcessExternalMarking(&root_visitor); 2238 ProcessEphemeralMarking(&root_visitor);
2242 2239
2243 // The objects reachable from the roots or object groups are marked, 2240 // The objects reachable from the roots, weak maps or object groups
2244 // yet unreachable objects are unmarked. Mark objects reachable 2241 // are marked, yet unreachable objects are unmarked. Mark objects
2245 // only from weak global handles. 2242 // reachable only from weak global handles.
2246 // 2243 //
2247 // First we identify nonlive weak handles and mark them as pending 2244 // First we identify nonlive weak handles and mark them as pending
2248 // destruction. 2245 // destruction.
2249 heap()->isolate()->global_handles()->IdentifyWeakHandles( 2246 heap()->isolate()->global_handles()->IdentifyWeakHandles(
2250 &IsUnmarkedHeapObject); 2247 &IsUnmarkedHeapObject);
2251 // Then we mark the objects and process the transitive closure. 2248 // Then we mark the objects and process the transitive closure.
2252 heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor); 2249 heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor);
2253 while (marking_deque_.overflowed()) { 2250 while (marking_deque_.overflowed()) {
2254 RefillMarkingDeque(); 2251 RefillMarkingDeque();
2255 EmptyMarkingDeque(); 2252 EmptyMarkingDeque();
2256 } 2253 }
2257 2254
2258 // Repeat host application specific marking to mark unmarked objects 2255 // Repeat host application specific and Harmony weak maps marking to
2259 // reachable from the weak roots. 2256 // mark unmarked objects reachable from the weak roots.
2260 ProcessExternalMarking(&root_visitor); 2257 ProcessEphemeralMarking(&root_visitor);
2261 2258
2262 AfterMarking(); 2259 AfterMarking();
2263 } 2260 }
2264 2261
2265 2262
2266 void MarkCompactCollector::AfterMarking() { 2263 void MarkCompactCollector::AfterMarking() {
2267 // Object literal map caches reference strings (cache keys) and maps 2264 // Object literal map caches reference strings (cache keys) and maps
2268 // (cache values). At this point still useful maps have already been 2265 // (cache values). At this point still useful maps have already been
2269 // marked. Mark the keys for the alive values before we process the 2266 // marked. Mark the keys for the alive values before we process the
2270 // string table. 2267 // string table.
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2522 group_number_of_entries); 2519 group_number_of_entries);
2523 new_number_of_entries += group_number_of_entries; 2520 new_number_of_entries += group_number_of_entries;
2524 } 2521 }
2525 for (int i = new_number_of_entries; i < number_of_entries; i++) { 2522 for (int i = new_number_of_entries; i < number_of_entries; i++) {
2526 entries->clear_code_at(i); 2523 entries->clear_code_at(i);
2527 } 2524 }
2528 } 2525 }
2529 2526
2530 2527
2531 void MarkCompactCollector::ProcessWeakMaps() { 2528 void MarkCompactCollector::ProcessWeakMaps() {
2529 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKMAP_PROCESS);
2532 Object* weak_map_obj = encountered_weak_maps(); 2530 Object* weak_map_obj = encountered_weak_maps();
2533 while (weak_map_obj != Smi::FromInt(0)) { 2531 while (weak_map_obj != Smi::FromInt(0)) {
2534 ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj))); 2532 ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
2535 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj); 2533 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
2536 ObjectHashTable* table = ObjectHashTable::cast(weak_map->table()); 2534 ObjectHashTable* table = ObjectHashTable::cast(weak_map->table());
2537 Object** anchor = reinterpret_cast<Object**>(table->address()); 2535 Object** anchor = reinterpret_cast<Object**>(table->address());
2538 for (int i = 0; i < table->Capacity(); i++) { 2536 for (int i = 0; i < table->Capacity(); i++) {
2539 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { 2537 if (MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
2540 Object** key_slot = 2538 Object** key_slot =
2541 HeapObject::RawField(table, FixedArray::OffsetOfElementAt( 2539 HeapObject::RawField(table, FixedArray::OffsetOfElementAt(
2542 ObjectHashTable::EntryToIndex(i))); 2540 ObjectHashTable::EntryToIndex(i)));
2543 RecordSlot(anchor, key_slot, *key_slot); 2541 RecordSlot(anchor, key_slot, *key_slot);
2544 Object** value_slot = 2542 Object** value_slot =
2545 HeapObject::RawField(table, FixedArray::OffsetOfElementAt( 2543 HeapObject::RawField(table, FixedArray::OffsetOfElementAt(
2546 ObjectHashTable::EntryToValueIndex(i))); 2544 ObjectHashTable::EntryToValueIndex(i)));
2547 MarkCompactMarkingVisitor::MarkObjectByPointer( 2545 MarkCompactMarkingVisitor::MarkObjectByPointer(
2548 this, anchor, value_slot); 2546 this, anchor, value_slot);
2549 } 2547 }
2550 } 2548 }
2551 weak_map_obj = weak_map->next(); 2549 weak_map_obj = weak_map->next();
2552 } 2550 }
2553 } 2551 }
2554 2552
2555 2553
2556 void MarkCompactCollector::ClearWeakMaps() { 2554 void MarkCompactCollector::ClearWeakMaps() {
2555 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_WEAKMAP_CLEAR);
2557 Object* weak_map_obj = encountered_weak_maps(); 2556 Object* weak_map_obj = encountered_weak_maps();
2558 while (weak_map_obj != Smi::FromInt(0)) { 2557 while (weak_map_obj != Smi::FromInt(0)) {
2559 ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj))); 2558 ASSERT(MarkCompactCollector::IsMarked(HeapObject::cast(weak_map_obj)));
2560 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj); 2559 JSWeakMap* weak_map = reinterpret_cast<JSWeakMap*>(weak_map_obj);
2561 ObjectHashTable* table = ObjectHashTable::cast(weak_map->table()); 2560 ObjectHashTable* table = ObjectHashTable::cast(weak_map->table());
2562 for (int i = 0; i < table->Capacity(); i++) { 2561 for (int i = 0; i < table->Capacity(); i++) {
2563 if (!MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) { 2562 if (!MarkCompactCollector::IsMarked(HeapObject::cast(table->KeyAt(i)))) {
2564 table->RemoveEntry(i); 2563 table->RemoveEntry(i);
2565 } 2564 }
2566 } 2565 }
(...skipping 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after
4243 while (buffer != NULL) { 4242 while (buffer != NULL) {
4244 SlotsBuffer* next_buffer = buffer->next(); 4243 SlotsBuffer* next_buffer = buffer->next();
4245 DeallocateBuffer(buffer); 4244 DeallocateBuffer(buffer);
4246 buffer = next_buffer; 4245 buffer = next_buffer;
4247 } 4246 }
4248 *buffer_address = NULL; 4247 *buffer_address = NULL;
4249 } 4248 }
4250 4249
4251 4250
4252 } } // namespace v8::internal 4251 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698