Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/mark-compact.h" | 5 #include "src/heap/mark-compact.h" |
| 6 | 6 |
| 7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/base/sys-info.h" | 9 #include "src/base/sys-info.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 2243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2254 GCTracer::Scope::MC_NONLIVEREFERENCES); | 2254 GCTracer::Scope::MC_NONLIVEREFERENCES); |
| 2255 // Iterate over the map space, setting map transitions that go from | 2255 // Iterate over the map space, setting map transitions that go from |
| 2256 // a marked map to an unmarked map to null transitions. This action | 2256 // a marked map to an unmarked map to null transitions. This action |
| 2257 // is carried out only on maps of JSObjects and related subtypes. | 2257 // is carried out only on maps of JSObjects and related subtypes. |
| 2258 HeapObjectIterator map_iterator(heap()->map_space()); | 2258 HeapObjectIterator map_iterator(heap()->map_space()); |
| 2259 for (HeapObject* obj = map_iterator.Next(); obj != NULL; | 2259 for (HeapObject* obj = map_iterator.Next(); obj != NULL; |
| 2260 obj = map_iterator.Next()) { | 2260 obj = map_iterator.Next()) { |
| 2261 Map* map = Map::cast(obj); | 2261 Map* map = Map::cast(obj); |
| 2262 if (!map->CanTransition()) continue; | 2262 if (!map->CanTransition()) continue; |
| 2263 MarkBit map_mark = Marking::MarkBitFrom(map); | 2263 MarkBit map_mark = Marking::MarkBitFrom(map); |
| 2264 bool alive = Marking::IsBlackOrGrey(map_mark); | 2264 if (Marking::IsWhite(map_mark)) { |
| 2265 if (alive) { | |
| 2266 ClearNonLivePrototypeTransitions(map); | |
| 2267 } else { | |
| 2268 ClearNonLiveMapTransitions(map); | 2265 ClearNonLiveMapTransitions(map); |
| 2269 } | 2266 } |
| 2270 } | 2267 } |
| 2271 | 2268 |
| 2272 WeakHashTable* table = heap_->weak_object_to_code_table(); | 2269 WeakHashTable* table = heap_->weak_object_to_code_table(); |
| 2273 uint32_t capacity = table->Capacity(); | 2270 uint32_t capacity = table->Capacity(); |
| 2274 for (uint32_t i = 0; i < capacity; i++) { | 2271 for (uint32_t i = 0; i < capacity; i++) { |
| 2275 uint32_t key_index = table->EntryToIndex(i); | 2272 uint32_t key_index = table->EntryToIndex(i); |
| 2276 Object* key = table->get(key_index); | 2273 Object* key = table->get(key_index); |
| 2277 if (!table->IsKey(key)) continue; | 2274 if (!table->IsKey(key)) continue; |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 2297 Isolate* isolate = this->isolate(); | 2294 Isolate* isolate = this->isolate(); |
| 2298 DependentCode* current = list_head; | 2295 DependentCode* current = list_head; |
| 2299 while (current->length() > 0) { | 2296 while (current->length() > 0) { |
| 2300 have_code_to_deoptimize_ |= current->MarkCodeForDeoptimization( | 2297 have_code_to_deoptimize_ |= current->MarkCodeForDeoptimization( |
| 2301 isolate, DependentCode::kWeakCodeGroup); | 2298 isolate, DependentCode::kWeakCodeGroup); |
| 2302 current = current->next_link(); | 2299 current = current->next_link(); |
| 2303 } | 2300 } |
| 2304 } | 2301 } |
| 2305 | 2302 |
| 2306 | 2303 |
| 2307 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { | |
| 2308 FixedArray* prototype_transitions = | |
|
ulan
2015/11/24 15:49:05
This code is moved to runtime.
| |
| 2309 TransitionArray::GetPrototypeTransitions(map); | |
| 2310 int number_of_transitions = | |
| 2311 TransitionArray::NumberOfPrototypeTransitions(prototype_transitions); | |
| 2312 | |
| 2313 const int header = TransitionArray::kProtoTransitionHeaderSize; | |
| 2314 int new_number_of_transitions = 0; | |
| 2315 for (int i = 0; i < number_of_transitions; i++) { | |
| 2316 Object* cell = prototype_transitions->get(header + i); | |
| 2317 if (!WeakCell::cast(cell)->cleared()) { | |
| 2318 if (new_number_of_transitions != i) { | |
| 2319 prototype_transitions->set(header + new_number_of_transitions, cell); | |
| 2320 Object** slot = prototype_transitions->RawFieldOfElementAt( | |
| 2321 header + new_number_of_transitions); | |
| 2322 RecordSlot(prototype_transitions, slot, cell); | |
| 2323 } | |
| 2324 new_number_of_transitions++; | |
| 2325 } | |
| 2326 } | |
| 2327 | |
| 2328 if (new_number_of_transitions != number_of_transitions) { | |
| 2329 TransitionArray::SetNumberOfPrototypeTransitions(prototype_transitions, | |
| 2330 new_number_of_transitions); | |
| 2331 } | |
| 2332 | |
| 2333 // Fill slots that became free with undefined value. | |
| 2334 for (int i = new_number_of_transitions; i < number_of_transitions; i++) { | |
| 2335 prototype_transitions->set_undefined(header + i); | |
| 2336 } | |
| 2337 } | |
| 2338 | |
| 2339 | |
| 2340 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map) { | 2304 void MarkCompactCollector::ClearNonLiveMapTransitions(Map* map) { |
| 2341 Object* potential_parent = map->GetBackPointer(); | 2305 Object* potential_parent = map->GetBackPointer(); |
| 2342 if (!potential_parent->IsMap()) return; | 2306 if (!potential_parent->IsMap()) return; |
| 2343 Map* parent = Map::cast(potential_parent); | 2307 Map* parent = Map::cast(potential_parent); |
| 2344 | 2308 |
| 2345 // Follow back pointer, check whether we are dealing with a map transition | 2309 // Follow back pointer, check whether we are dealing with a map transition |
| 2346 // from a live map to a dead path and in case clear transitions of parent. | 2310 // from a live map to a dead path and in case clear transitions of parent. |
| 2347 DCHECK(!Marking::IsBlackOrGrey(Marking::MarkBitFrom(map))); | 2311 DCHECK(!Marking::IsBlackOrGrey(Marking::MarkBitFrom(map))); |
| 2348 bool parent_is_alive = Marking::IsBlackOrGrey(Marking::MarkBitFrom(parent)); | 2312 bool parent_is_alive = Marking::IsBlackOrGrey(Marking::MarkBitFrom(parent)); |
| 2349 if (parent_is_alive) { | 2313 if (parent_is_alive) { |
| (...skipping 2204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4554 MarkBit mark_bit = Marking::MarkBitFrom(host); | 4518 MarkBit mark_bit = Marking::MarkBitFrom(host); |
| 4555 if (Marking::IsBlack(mark_bit)) { | 4519 if (Marking::IsBlack(mark_bit)) { |
| 4556 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); | 4520 RelocInfo rinfo(pc, RelocInfo::CODE_TARGET, 0, host); |
| 4557 RecordRelocSlot(&rinfo, target); | 4521 RecordRelocSlot(&rinfo, target); |
| 4558 } | 4522 } |
| 4559 } | 4523 } |
| 4560 } | 4524 } |
| 4561 | 4525 |
| 4562 } // namespace internal | 4526 } // namespace internal |
| 4563 } // namespace v8 | 4527 } // namespace v8 |
| OLD | NEW |