| 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 |