OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |