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

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

Issue 145773008: A64: Synchronize with r17104. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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') | src/marking-thread.h » ('j') | 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 20 matching lines...) Expand all
31 #include "compilation-cache.h" 31 #include "compilation-cache.h"
32 #include "cpu-profiler.h" 32 #include "cpu-profiler.h"
33 #include "deoptimizer.h" 33 #include "deoptimizer.h"
34 #include "execution.h" 34 #include "execution.h"
35 #include "gdb-jit.h" 35 #include "gdb-jit.h"
36 #include "global-handles.h" 36 #include "global-handles.h"
37 #include "heap-profiler.h" 37 #include "heap-profiler.h"
38 #include "ic-inl.h" 38 #include "ic-inl.h"
39 #include "incremental-marking.h" 39 #include "incremental-marking.h"
40 #include "mark-compact.h" 40 #include "mark-compact.h"
41 #include "marking-thread.h"
42 #include "objects-visiting.h" 41 #include "objects-visiting.h"
43 #include "objects-visiting-inl.h" 42 #include "objects-visiting-inl.h"
44 #include "stub-cache.h" 43 #include "stub-cache.h"
45 #include "sweeper-thread.h" 44 #include "sweeper-thread.h"
46 45
47 namespace v8 { 46 namespace v8 {
48 namespace internal { 47 namespace internal {
49 48
50 49
51 const char* Marking::kWhiteBitPattern = "00"; 50 const char* Marking::kWhiteBitPattern = "00";
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 for (Object** current = start; current < end; current++) { 84 for (Object** current = start; current < end; current++) {
86 if ((*current)->IsHeapObject()) { 85 if ((*current)->IsHeapObject()) {
87 HeapObject* object = HeapObject::cast(*current); 86 HeapObject* object = HeapObject::cast(*current);
88 CHECK(heap_->mark_compact_collector()->IsMarked(object)); 87 CHECK(heap_->mark_compact_collector()->IsMarked(object));
89 } 88 }
90 } 89 }
91 } 90 }
92 91
93 void VisitEmbeddedPointer(RelocInfo* rinfo) { 92 void VisitEmbeddedPointer(RelocInfo* rinfo) {
94 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); 93 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT);
95 if (!FLAG_weak_embedded_maps_in_optimized_code || !FLAG_collect_maps || 94 if (!Code::IsWeakEmbeddedObject(rinfo->host()->kind(),
96 rinfo->host()->kind() != Code::OPTIMIZED_FUNCTION || 95 rinfo->target_object())) {
97 !rinfo->target_object()->IsMap() ||
98 !Map::cast(rinfo->target_object())->CanTransition()) {
99 VisitPointer(rinfo->target_object_address()); 96 VisitPointer(rinfo->target_object_address());
100 } 97 }
101 } 98 }
102 99
103 private: 100 private:
104 Heap* heap_; 101 Heap* heap_;
105 }; 102 };
106 103
107 104
108 static void VerifyMarking(Heap* heap, Address bottom, Address top) { 105 static void VerifyMarking(Heap* heap, Address bottom, Address top) {
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 return compacting_; 398 return compacting_;
402 } 399 }
403 400
404 401
405 void MarkCompactCollector::CollectGarbage() { 402 void MarkCompactCollector::CollectGarbage() {
406 // Make sure that Prepare() has been called. The individual steps below will 403 // Make sure that Prepare() has been called. The individual steps below will
407 // update the state as they proceed. 404 // update the state as they proceed.
408 ASSERT(state_ == PREPARE_GC); 405 ASSERT(state_ == PREPARE_GC);
409 ASSERT(encountered_weak_collections_ == Smi::FromInt(0)); 406 ASSERT(encountered_weak_collections_ == Smi::FromInt(0));
410 407
408 heap()->allocation_mementos_found_ = 0;
409
411 MarkLiveObjects(); 410 MarkLiveObjects();
412 ASSERT(heap_->incremental_marking()->IsStopped()); 411 ASSERT(heap_->incremental_marking()->IsStopped());
413 412
414 if (FLAG_collect_maps) ClearNonLiveReferences(); 413 if (FLAG_collect_maps) ClearNonLiveReferences();
415 414
416 ClearWeakCollections(); 415 ClearWeakCollections();
417 416
418 #ifdef VERIFY_HEAP 417 #ifdef VERIFY_HEAP
419 if (FLAG_verify_heap) { 418 if (FLAG_verify_heap) {
420 VerifyMarking(heap_); 419 VerifyMarking(heap_);
421 } 420 }
422 #endif 421 #endif
423 422
424 SweepSpaces(); 423 SweepSpaces();
425 424
426 if (!FLAG_collect_maps) ReattachInitialMaps(); 425 if (!FLAG_collect_maps) ReattachInitialMaps();
427 426
428 #ifdef DEBUG 427 #ifdef DEBUG
429 if (FLAG_verify_native_context_separation) { 428 if (FLAG_verify_native_context_separation) {
430 VerifyNativeContextSeparation(heap_); 429 VerifyNativeContextSeparation(heap_);
431 } 430 }
432 #endif 431 #endif
433 432
434 #ifdef VERIFY_HEAP 433 #ifdef VERIFY_HEAP
435 if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_optimized_code && 434 if (heap()->weak_embedded_objects_verification_enabled()) {
436 heap()->weak_embedded_maps_verification_enabled()) { 435 VerifyWeakEmbeddedObjectsInOptimizedCode();
437 VerifyWeakEmbeddedMapsInOptimizedCode();
438 } 436 }
439 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) { 437 if (FLAG_collect_maps && FLAG_omit_map_checks_for_leaf_maps) {
440 VerifyOmittedMapChecks(); 438 VerifyOmittedMapChecks();
441 } 439 }
442 #endif 440 #endif
443 441
444 Finish(); 442 Finish();
445 443
446 if (marking_parity_ == EVEN_MARKING_PARITY) { 444 if (marking_parity_ == EVEN_MARKING_PARITY) {
447 marking_parity_ = ODD_MARKING_PARITY; 445 marking_parity_ = ODD_MARKING_PARITY;
448 } else { 446 } else {
449 ASSERT(marking_parity_ == ODD_MARKING_PARITY); 447 ASSERT(marking_parity_ == ODD_MARKING_PARITY);
450 marking_parity_ = EVEN_MARKING_PARITY; 448 marking_parity_ = EVEN_MARKING_PARITY;
451 } 449 }
452 450
451 if (FLAG_trace_track_allocation_sites &&
452 heap()->allocation_mementos_found_ > 0) {
453 PrintF("AllocationMementos found during mark-sweep = %d\n",
454 heap()->allocation_mementos_found_);
455 }
453 tracer_ = NULL; 456 tracer_ = NULL;
454 } 457 }
455 458
456 459
457 #ifdef VERIFY_HEAP 460 #ifdef VERIFY_HEAP
458 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) { 461 void MarkCompactCollector::VerifyMarkbitsAreClean(PagedSpace* space) {
459 PageIterator it(space); 462 PageIterator it(space);
460 463
461 while (it.has_next()) { 464 while (it.has_next()) {
462 Page* p = it.next(); 465 Page* p = it.next();
(...skipping 25 matching lines...) Expand all
488 491
489 LargeObjectIterator it(heap_->lo_space()); 492 LargeObjectIterator it(heap_->lo_space());
490 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 493 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
491 MarkBit mark_bit = Marking::MarkBitFrom(obj); 494 MarkBit mark_bit = Marking::MarkBitFrom(obj);
492 CHECK(Marking::IsWhite(mark_bit)); 495 CHECK(Marking::IsWhite(mark_bit));
493 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes()); 496 CHECK_EQ(0, Page::FromAddress(obj->address())->LiveBytes());
494 } 497 }
495 } 498 }
496 499
497 500
498 void MarkCompactCollector::VerifyWeakEmbeddedMapsInOptimizedCode() { 501 void MarkCompactCollector::VerifyWeakEmbeddedObjectsInOptimizedCode() {
499 HeapObjectIterator code_iterator(heap()->code_space()); 502 HeapObjectIterator code_iterator(heap()->code_space());
500 for (HeapObject* obj = code_iterator.Next(); 503 for (HeapObject* obj = code_iterator.Next();
501 obj != NULL; 504 obj != NULL;
502 obj = code_iterator.Next()) { 505 obj = code_iterator.Next()) {
503 Code* code = Code::cast(obj); 506 Code* code = Code::cast(obj);
504 if (code->kind() != Code::OPTIMIZED_FUNCTION) continue; 507 if (code->kind() != Code::OPTIMIZED_FUNCTION) continue;
505 if (WillBeDeoptimized(code)) continue; 508 if (WillBeDeoptimized(code)) continue;
506 code->VerifyEmbeddedMapsDependency(); 509 code->VerifyEmbeddedObjectsDependency();
507 } 510 }
508 } 511 }
509 512
510 513
511 void MarkCompactCollector::VerifyOmittedMapChecks() { 514 void MarkCompactCollector::VerifyOmittedMapChecks() {
512 HeapObjectIterator iterator(heap()->map_space()); 515 HeapObjectIterator iterator(heap()->map_space());
513 for (HeapObject* obj = iterator.Next(); 516 for (HeapObject* obj = iterator.Next();
514 obj != NULL; 517 obj != NULL;
515 obj = iterator.Next()) { 518 obj = iterator.Next()) {
516 Map* map = Map::cast(obj); 519 Map* map = Map::cast(obj);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 bool MarkCompactCollector::AreSweeperThreadsActivated() { 597 bool MarkCompactCollector::AreSweeperThreadsActivated() {
595 return isolate()->sweeper_threads() != NULL; 598 return isolate()->sweeper_threads() != NULL;
596 } 599 }
597 600
598 601
599 bool MarkCompactCollector::IsConcurrentSweepingInProgress() { 602 bool MarkCompactCollector::IsConcurrentSweepingInProgress() {
600 return sweeping_pending_; 603 return sweeping_pending_;
601 } 604 }
602 605
603 606
604 void MarkCompactCollector::MarkInParallel() {
605 for (int i = 0; i < FLAG_marking_threads; i++) {
606 isolate()->marking_threads()[i]->StartMarking();
607 }
608 }
609
610
611 void MarkCompactCollector::WaitUntilMarkingCompleted() {
612 for (int i = 0; i < FLAG_marking_threads; i++) {
613 isolate()->marking_threads()[i]->WaitForMarkingThread();
614 }
615 }
616
617
618 bool Marking::TransferMark(Address old_start, Address new_start) { 607 bool Marking::TransferMark(Address old_start, Address new_start) {
619 // This is only used when resizing an object. 608 // This is only used when resizing an object.
620 ASSERT(MemoryChunk::FromAddress(old_start) == 609 ASSERT(MemoryChunk::FromAddress(old_start) ==
621 MemoryChunk::FromAddress(new_start)); 610 MemoryChunk::FromAddress(new_start));
622 611
623 // If the mark doesn't move, we don't check the color of the object. 612 // If the mark doesn't move, we don't check the color of the object.
624 // It doesn't matter whether the object is black, since it hasn't changed 613 // It doesn't matter whether the object is black, since it hasn't changed
625 // size, so the adjustment to the live data count will be zero anyway. 614 // size, so the adjustment to the live data count will be zero anyway.
626 if (old_start == new_start) return false; 615 if (old_start == new_start) return false;
627 616
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 JSWeakCollection::kTableOffset); 1463 JSWeakCollection::kTableOffset);
1475 BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers( 1464 BodyVisitorBase<MarkCompactMarkingVisitor>::IteratePointers(
1476 map->GetHeap(), 1465 map->GetHeap(),
1477 object, 1466 object,
1478 JSWeakCollection::kTableOffset + kPointerSize, 1467 JSWeakCollection::kTableOffset + kPointerSize,
1479 object_size); 1468 object_size);
1480 1469
1481 // Mark the backing hash table without pushing it on the marking stack. 1470 // Mark the backing hash table without pushing it on the marking stack.
1482 Object* table_object = weak_collection->table(); 1471 Object* table_object = weak_collection->table();
1483 if (!table_object->IsHashTable()) return; 1472 if (!table_object->IsHashTable()) return;
1484 ObjectHashTable* table = ObjectHashTable::cast(table_object); 1473 WeakHashTable* table = WeakHashTable::cast(table_object);
1485 Object** table_slot = 1474 Object** table_slot =
1486 HeapObject::RawField(weak_collection, JSWeakCollection::kTableOffset); 1475 HeapObject::RawField(weak_collection, JSWeakCollection::kTableOffset);
1487 MarkBit table_mark = Marking::MarkBitFrom(table); 1476 MarkBit table_mark = Marking::MarkBitFrom(table);
1488 collector->RecordSlot(table_slot, table_slot, table); 1477 collector->RecordSlot(table_slot, table_slot, table);
1489 if (!table_mark.Get()) collector->SetMark(table, table_mark); 1478 if (!table_mark.Get()) collector->SetMark(table, table_mark);
1490 // Recording the map slot can be skipped, because maps are not compacted. 1479 // Recording the map slot can be skipped, because maps are not compacted.
1491 collector->MarkObject(table->map(), Marking::MarkBitFrom(table->map())); 1480 collector->MarkObject(table->map(), Marking::MarkBitFrom(table->map()));
1492 ASSERT(MarkCompactCollector::IsMarked(table->map())); 1481 ASSERT(MarkCompactCollector::IsMarked(table->map()));
1493 } 1482 }
1494 1483
(...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after
2010 while (current_cell != 0) { 1999 while (current_cell != 0) {
2011 int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(current_cell); 2000 int trailing_zeros = CompilerIntrinsics::CountTrailingZeros(current_cell);
2012 current_cell >>= trailing_zeros; 2001 current_cell >>= trailing_zeros;
2013 offset += trailing_zeros; 2002 offset += trailing_zeros;
2014 Address address = cell_base + offset * kPointerSize; 2003 Address address = cell_base + offset * kPointerSize;
2015 HeapObject* object = HeapObject::FromAddress(address); 2004 HeapObject* object = HeapObject::FromAddress(address);
2016 2005
2017 int size = object->Size(); 2006 int size = object->Size();
2018 survivors_size += size; 2007 survivors_size += size;
2019 2008
2009 if (FLAG_trace_track_allocation_sites && object->IsJSObject()) {
2010 if (AllocationMemento::FindForJSObject(JSObject::cast(object), true)
2011 != NULL) {
2012 heap()->allocation_mementos_found_++;
2013 }
2014 }
2015
2020 offset++; 2016 offset++;
2021 current_cell >>= 1; 2017 current_cell >>= 1;
2022 // Aggressively promote young survivors to the old space. 2018 // Aggressively promote young survivors to the old space.
2023 if (TryPromoteObject(object, size)) { 2019 if (TryPromoteObject(object, size)) {
2024 continue; 2020 continue;
2025 } 2021 }
2026 2022
2027 // Promotion failed. Just migrate object to another semispace. 2023 // Promotion failed. Just migrate object to another semispace.
2028 MaybeObject* allocation = new_space->AllocateRaw(size); 2024 MaybeObject* allocation = new_space->AllocateRaw(size);
2029 if (allocation->IsFailure()) { 2025 if (allocation->IsFailure()) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2109 2105
2110 2106
2111 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { 2107 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) {
2112 // Mark the heap roots including global variables, stack variables, 2108 // Mark the heap roots including global variables, stack variables,
2113 // etc., and all objects reachable from them. 2109 // etc., and all objects reachable from them.
2114 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); 2110 heap()->IterateStrongRoots(visitor, VISIT_ONLY_STRONG);
2115 2111
2116 // Handle the string table specially. 2112 // Handle the string table specially.
2117 MarkStringTable(visitor); 2113 MarkStringTable(visitor);
2118 2114
2115 MarkWeakObjectToCodeTable();
2116
2119 // There may be overflowed objects in the heap. Visit them now. 2117 // There may be overflowed objects in the heap. Visit them now.
2120 while (marking_deque_.overflowed()) { 2118 while (marking_deque_.overflowed()) {
2121 RefillMarkingDeque(); 2119 RefillMarkingDeque();
2122 EmptyMarkingDeque(); 2120 EmptyMarkingDeque();
2123 } 2121 }
2124 } 2122 }
2125 2123
2126 2124
2127 void MarkCompactCollector::MarkImplicitRefGroups() { 2125 void MarkCompactCollector::MarkImplicitRefGroups() {
2128 List<ImplicitRefGroup*>* ref_groups = 2126 List<ImplicitRefGroup*>* ref_groups =
(...skipping 20 matching lines...) Expand all
2149 } 2147 }
2150 2148
2151 // Once the entire group has been marked, dispose it because it's 2149 // Once the entire group has been marked, dispose it because it's
2152 // not needed anymore. 2150 // not needed anymore.
2153 delete entry; 2151 delete entry;
2154 } 2152 }
2155 ref_groups->Rewind(last); 2153 ref_groups->Rewind(last);
2156 } 2154 }
2157 2155
2158 2156
2157 void MarkCompactCollector::MarkWeakObjectToCodeTable() {
2158 HeapObject* weak_object_to_code_table =
2159 HeapObject::cast(heap()->weak_object_to_code_table());
2160 if (!IsMarked(weak_object_to_code_table)) {
2161 MarkBit mark = Marking::MarkBitFrom(weak_object_to_code_table);
2162 SetMark(weak_object_to_code_table, mark);
2163 }
2164 }
2165
2166
2159 // Mark all objects reachable from the objects on the marking stack. 2167 // Mark all objects reachable from the objects on the marking stack.
2160 // Before: the marking stack contains zero or more heap object pointers. 2168 // Before: the marking stack contains zero or more heap object pointers.
2161 // After: the marking stack is empty, and all objects reachable from the 2169 // After: the marking stack is empty, and all objects reachable from the
2162 // marking stack have been marked, or are overflowed in the heap. 2170 // marking stack have been marked, or are overflowed in the heap.
2163 void MarkCompactCollector::EmptyMarkingDeque() { 2171 void MarkCompactCollector::EmptyMarkingDeque() {
2164 while (!marking_deque_.IsEmpty()) { 2172 while (!marking_deque_.IsEmpty()) {
2165 HeapObject* object = marking_deque_.Pop(); 2173 HeapObject* object = marking_deque_.Pop();
2166 ASSERT(object->IsHeapObject()); 2174 ASSERT(object->IsHeapObject());
2167 ASSERT(heap()->Contains(object)); 2175 ASSERT(heap()->Contains(object));
2168 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object))); 2176 ASSERT(Marking::IsBlack(Marking::MarkBitFrom(object)));
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
2516 // Since it survived the GC, reattach it now. 2524 // Since it survived the GC, reattach it now.
2517 JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map); 2525 JSFunction::cast(map->constructor())->shared()->AttachInitialMap(map);
2518 } 2526 }
2519 2527
2520 ClearNonLivePrototypeTransitions(map); 2528 ClearNonLivePrototypeTransitions(map);
2521 ClearNonLiveMapTransitions(map, map_mark); 2529 ClearNonLiveMapTransitions(map, map_mark);
2522 2530
2523 if (map_mark.Get()) { 2531 if (map_mark.Get()) {
2524 ClearNonLiveDependentCode(map->dependent_code()); 2532 ClearNonLiveDependentCode(map->dependent_code());
2525 } else { 2533 } else {
2526 ClearAndDeoptimizeDependentCode(map); 2534 ClearAndDeoptimizeDependentCode(map->dependent_code());
2535 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
2527 } 2536 }
2528 } 2537 }
2529 2538
2530 // Iterate over property cell space, removing dependent code that is not 2539 // Iterate over property cell space, removing dependent code that is not
2531 // otherwise kept alive by strong references. 2540 // otherwise kept alive by strong references.
2532 HeapObjectIterator cell_iterator(heap_->property_cell_space()); 2541 HeapObjectIterator cell_iterator(heap_->property_cell_space());
2533 for (HeapObject* cell = cell_iterator.Next(); 2542 for (HeapObject* cell = cell_iterator.Next();
2534 cell != NULL; 2543 cell != NULL;
2535 cell = cell_iterator.Next()) { 2544 cell = cell_iterator.Next()) {
2536 if (IsMarked(cell)) { 2545 if (IsMarked(cell)) {
2537 ClearNonLiveDependentCode(PropertyCell::cast(cell)->dependent_code()); 2546 ClearNonLiveDependentCode(PropertyCell::cast(cell)->dependent_code());
2538 } 2547 }
2539 } 2548 }
2549
2550 if (heap_->weak_object_to_code_table()->IsHashTable()) {
2551 WeakHashTable* table =
2552 WeakHashTable::cast(heap_->weak_object_to_code_table());
2553 uint32_t capacity = table->Capacity();
2554 for (uint32_t i = 0; i < capacity; i++) {
2555 uint32_t key_index = table->EntryToIndex(i);
2556 Object* key = table->get(key_index);
2557 if (!table->IsKey(key)) continue;
2558 uint32_t value_index = table->EntryToValueIndex(i);
2559 Object* value = table->get(value_index);
2560 if (IsMarked(key)) {
2561 if (!IsMarked(value)) {
2562 HeapObject* obj = HeapObject::cast(value);
2563 MarkBit mark = Marking::MarkBitFrom(obj);
2564 SetMark(obj, mark);
2565 }
2566 ClearNonLiveDependentCode(DependentCode::cast(value));
2567 } else {
2568 ClearAndDeoptimizeDependentCode(DependentCode::cast(value));
2569 table->set(key_index, heap_->the_hole_value());
2570 table->set(value_index, heap_->the_hole_value());
2571 }
2572 }
2573 }
2540 } 2574 }
2541 2575
2542 2576
2543 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) { 2577 void MarkCompactCollector::ClearNonLivePrototypeTransitions(Map* map) {
2544 int number_of_transitions = map->NumberOfProtoTransitions(); 2578 int number_of_transitions = map->NumberOfProtoTransitions();
2545 FixedArray* prototype_transitions = map->GetPrototypeTransitions(); 2579 FixedArray* prototype_transitions = map->GetPrototypeTransitions();
2546 2580
2547 int new_number_of_transitions = 0; 2581 int new_number_of_transitions = 0;
2548 const int header = Map::kProtoTransitionHeaderSize; 2582 const int header = Map::kProtoTransitionHeaderSize;
2549 const int proto_offset = header + Map::kProtoTransitionPrototypeOffset; 2583 const int proto_offset = header + Map::kProtoTransitionPrototypeOffset;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
2595 // Follow back pointer, check whether we are dealing with a map transition 2629 // Follow back pointer, check whether we are dealing with a map transition
2596 // from a live map to a dead path and in case clear transitions of parent. 2630 // from a live map to a dead path and in case clear transitions of parent.
2597 bool current_is_alive = map_mark.Get(); 2631 bool current_is_alive = map_mark.Get();
2598 bool parent_is_alive = Marking::MarkBitFrom(parent).Get(); 2632 bool parent_is_alive = Marking::MarkBitFrom(parent).Get();
2599 if (!current_is_alive && parent_is_alive) { 2633 if (!current_is_alive && parent_is_alive) {
2600 parent->ClearNonLiveTransitions(heap()); 2634 parent->ClearNonLiveTransitions(heap());
2601 } 2635 }
2602 } 2636 }
2603 2637
2604 2638
2605 void MarkCompactCollector::ClearAndDeoptimizeDependentCode(Map* map) { 2639 void MarkCompactCollector::ClearAndDeoptimizeDependentCode(
2640 DependentCode* entries) {
2606 DisallowHeapAllocation no_allocation; 2641 DisallowHeapAllocation no_allocation;
2607 DependentCode* entries = map->dependent_code();
2608 DependentCode::GroupStartIndexes starts(entries); 2642 DependentCode::GroupStartIndexes starts(entries);
2609 int number_of_entries = starts.number_of_entries(); 2643 int number_of_entries = starts.number_of_entries();
2610 if (number_of_entries == 0) return; 2644 if (number_of_entries == 0) return;
2611 for (int i = 0; i < number_of_entries; i++) { 2645 for (int i = 0; i < number_of_entries; i++) {
2612 // If the entry is compilation info then the map must be alive, 2646 // If the entry is compilation info then the map must be alive,
2613 // and ClearAndDeoptimizeDependentCode shouldn't be called. 2647 // and ClearAndDeoptimizeDependentCode shouldn't be called.
2614 ASSERT(entries->is_code_at(i)); 2648 ASSERT(entries->is_code_at(i));
2615 Code* code = entries->code_at(i); 2649 Code* code = entries->code_at(i);
2616 2650
2617 if (IsMarked(code) && !code->marked_for_deoptimization()) { 2651 if (IsMarked(code) && !code->marked_for_deoptimization()) {
2618 code->set_marked_for_deoptimization(true); 2652 code->set_marked_for_deoptimization(true);
2619 have_code_to_deoptimize_ = true; 2653 have_code_to_deoptimize_ = true;
2620 } 2654 }
2621 entries->clear_at(i); 2655 entries->clear_at(i);
2622 } 2656 }
2623 map->set_dependent_code(DependentCode::cast(heap()->empty_fixed_array()));
2624 } 2657 }
2625 2658
2626 2659
2627 void MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) { 2660 void MarkCompactCollector::ClearNonLiveDependentCode(DependentCode* entries) {
2628 DisallowHeapAllocation no_allocation; 2661 DisallowHeapAllocation no_allocation;
2629 DependentCode::GroupStartIndexes starts(entries); 2662 DependentCode::GroupStartIndexes starts(entries);
2630 int number_of_entries = starts.number_of_entries(); 2663 int number_of_entries = starts.number_of_entries();
2631 if (number_of_entries == 0) return; 2664 if (number_of_entries == 0) return;
2632 int new_number_of_entries = 0; 2665 int new_number_of_entries = 0;
2633 // Go through all groups, remove dead codes and compact. 2666 // Go through all groups, remove dead codes and compact.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2720 // to encounter pointers to dead new space objects during traversal of pointers 2753 // to encounter pointers to dead new space objects during traversal of pointers
2721 // to new space. We should clear them to avoid encountering them during next 2754 // to new space. We should clear them to avoid encountering them during next
2722 // pointer iteration. This is an issue if the store buffer overflows and we 2755 // pointer iteration. This is an issue if the store buffer overflows and we
2723 // have to scan the entire old space, including dead objects, looking for 2756 // have to scan the entire old space, including dead objects, looking for
2724 // pointers to new space. 2757 // pointers to new space.
2725 void MarkCompactCollector::MigrateObject(Address dst, 2758 void MarkCompactCollector::MigrateObject(Address dst,
2726 Address src, 2759 Address src,
2727 int size, 2760 int size,
2728 AllocationSpace dest) { 2761 AllocationSpace dest) {
2729 HEAP_PROFILE(heap(), ObjectMoveEvent(src, dst)); 2762 HEAP_PROFILE(heap(), ObjectMoveEvent(src, dst));
2730 // TODO(hpayer): Replace these checks with asserts. 2763 ASSERT(heap()->AllowedToBeMigrated(HeapObject::FromAddress(src), dest));
2731 CHECK(heap()->AllowedToBeMigrated(HeapObject::FromAddress(src), dest)); 2764 ASSERT(dest != LO_SPACE && size <= Page::kMaxNonCodeHeapObjectSize);
2732 CHECK(dest != LO_SPACE && size <= Page::kMaxNonCodeHeapObjectSize);
2733 if (dest == OLD_POINTER_SPACE) { 2765 if (dest == OLD_POINTER_SPACE) {
2734 Address src_slot = src; 2766 Address src_slot = src;
2735 Address dst_slot = dst; 2767 Address dst_slot = dst;
2736 ASSERT(IsAligned(size, kPointerSize)); 2768 ASSERT(IsAligned(size, kPointerSize));
2737 2769
2738 for (int remaining = size / kPointerSize; remaining > 0; remaining--) { 2770 for (int remaining = size / kPointerSize; remaining > 0; remaining--) {
2739 Object* value = Memory::Object_at(src_slot); 2771 Object* value = Memory::Object_at(src_slot);
2740 2772
2741 Memory::Object_at(dst_slot) = value; 2773 Memory::Object_at(dst_slot) = value;
2742 2774
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after
3452 cell = js_global_property_cell_iterator.Next()) { 3484 cell = js_global_property_cell_iterator.Next()) {
3453 if (cell->IsPropertyCell()) { 3485 if (cell->IsPropertyCell()) {
3454 PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor); 3486 PropertyCell::BodyDescriptor::IterateBody(cell, &updating_visitor);
3455 } 3487 }
3456 } 3488 }
3457 3489
3458 // Update the head of the native contexts list in the heap. 3490 // Update the head of the native contexts list in the heap.
3459 updating_visitor.VisitPointer(heap_->native_contexts_list_address()); 3491 updating_visitor.VisitPointer(heap_->native_contexts_list_address());
3460 3492
3461 heap_->string_table()->Iterate(&updating_visitor); 3493 heap_->string_table()->Iterate(&updating_visitor);
3494 updating_visitor.VisitPointer(heap_->weak_object_to_code_table_address());
3495 if (heap_->weak_object_to_code_table()->IsHashTable()) {
3496 WeakHashTable* table =
3497 WeakHashTable::cast(heap_->weak_object_to_code_table());
3498 table->Iterate(&updating_visitor);
3499 table->Rehash(heap_->undefined_value());
3500 }
3462 3501
3463 // Update pointers from external string table. 3502 // Update pointers from external string table.
3464 heap_->UpdateReferencesInExternalStringTable( 3503 heap_->UpdateReferencesInExternalStringTable(
3465 &UpdateReferenceInExternalStringTableEntry); 3504 &UpdateReferenceInExternalStringTableEntry);
3466 3505
3467 if (!FLAG_watch_ic_patching) { 3506 if (!FLAG_watch_ic_patching) {
3468 // Update JSFunction pointers from the runtime profiler. 3507 // Update JSFunction pointers from the runtime profiler.
3469 heap()->isolate()->runtime_profiler()->UpdateSamplesAfterCompact( 3508 heap()->isolate()->runtime_profiler()->UpdateSamplesAfterCompact(
3470 &updating_visitor); 3509 &updating_visitor);
3471 } 3510 }
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after
4315 while (buffer != NULL) { 4354 while (buffer != NULL) {
4316 SlotsBuffer* next_buffer = buffer->next(); 4355 SlotsBuffer* next_buffer = buffer->next();
4317 DeallocateBuffer(buffer); 4356 DeallocateBuffer(buffer);
4318 buffer = next_buffer; 4357 buffer = next_buffer;
4319 } 4358 }
4320 *buffer_address = NULL; 4359 *buffer_address = NULL;
4321 } 4360 }
4322 4361
4323 4362
4324 } } // namespace v8::internal 4363 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/marking-thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698