| OLD | NEW | 
|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 61       live_code_objects_size_(0), | 61       live_code_objects_size_(0), | 
| 62       live_map_objects_size_(0), | 62       live_map_objects_size_(0), | 
| 63       live_cell_objects_size_(0), | 63       live_cell_objects_size_(0), | 
| 64       live_lo_objects_size_(0), | 64       live_lo_objects_size_(0), | 
| 65       live_bytes_(0), | 65       live_bytes_(0), | 
| 66 #endif | 66 #endif | 
| 67       heap_(NULL), | 67       heap_(NULL), | 
| 68       code_flusher_(NULL) { } | 68       code_flusher_(NULL) { } | 
| 69 | 69 | 
| 70 | 70 | 
| 71 bool Marking::Setup() { |  | 
| 72   if (new_space_bitmap_ == NULL) { |  | 
| 73     // TODO(gc) ISOLATES |  | 
| 74     int markbits_per_newspace = |  | 
| 75         (2*HEAP->ReservedSemiSpaceSize()) >> kPointerSizeLog2; |  | 
| 76 |  | 
| 77     new_space_bitmap_ = |  | 
| 78         BitmapStorageDescriptor::Allocate( |  | 
| 79             NewSpaceMarkbitsBitmap::CellsForLength(markbits_per_newspace)); |  | 
| 80   } |  | 
| 81   return new_space_bitmap_ != NULL; |  | 
| 82 } |  | 
| 83 |  | 
| 84 |  | 
| 85 void Marking::TearDown() { |  | 
| 86   if (new_space_bitmap_ != NULL) { |  | 
| 87     BitmapStorageDescriptor::Free(new_space_bitmap_); |  | 
| 88     new_space_bitmap_ = NULL; |  | 
| 89   } |  | 
| 90 } |  | 
| 91 |  | 
| 92 |  | 
| 93 #ifdef DEBUG | 71 #ifdef DEBUG | 
| 94 class VerifyMarkingVisitor: public ObjectVisitor { | 72 class VerifyMarkingVisitor: public ObjectVisitor { | 
| 95  public: | 73  public: | 
| 96   void VisitPointers(Object** start, Object** end) { | 74   void VisitPointers(Object** start, Object** end) { | 
| 97     for (Object** current = start; current < end; current++) { | 75     for (Object** current = start; current < end; current++) { | 
| 98       if ((*current)->IsHeapObject()) { | 76       if ((*current)->IsHeapObject()) { | 
| 99         HeapObject* object = HeapObject::cast(*current); | 77         HeapObject* object = HeapObject::cast(*current); | 
| 100         ASSERT(HEAP->mark_compact_collector()->IsMarked(object)); | 78         ASSERT(HEAP->mark_compact_collector()->IsMarked(object)); | 
| 101       } | 79       } | 
| 102     } | 80     } | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 205     ASSERT(p->markbits()->IsClean()); | 183     ASSERT(p->markbits()->IsClean()); | 
| 206   } | 184   } | 
| 207 } | 185 } | 
| 208 | 186 | 
| 209 static void VerifyMarkbitsAreClean() { | 187 static void VerifyMarkbitsAreClean() { | 
| 210   VerifyMarkbitsAreClean(HEAP->old_pointer_space()); | 188   VerifyMarkbitsAreClean(HEAP->old_pointer_space()); | 
| 211   VerifyMarkbitsAreClean(HEAP->old_data_space()); | 189   VerifyMarkbitsAreClean(HEAP->old_data_space()); | 
| 212   VerifyMarkbitsAreClean(HEAP->code_space()); | 190   VerifyMarkbitsAreClean(HEAP->code_space()); | 
| 213   VerifyMarkbitsAreClean(HEAP->cell_space()); | 191   VerifyMarkbitsAreClean(HEAP->cell_space()); | 
| 214   VerifyMarkbitsAreClean(HEAP->map_space()); | 192   VerifyMarkbitsAreClean(HEAP->map_space()); | 
|  | 193   ASSERT(HEAP->new_space()->ActivePage()->markbits()->IsClean()); | 
| 215 } | 194 } | 
| 216 #endif | 195 #endif | 
| 217 | 196 | 
| 218 | 197 | 
| 219 static void ClearMarkbits(PagedSpace* space) { | 198 static void ClearMarkbits(PagedSpace* space) { | 
| 220   PageIterator it(space); | 199   PageIterator it(space); | 
| 221 | 200 | 
| 222   while (it.has_next()) { | 201   while (it.has_next()) { | 
| 223     Page* p = it.next(); | 202     Page* p = it.next(); | 
| 224     p->markbits()->Clear(); | 203     p->markbits()->Clear(); | 
| 225   } | 204   } | 
| 226 } | 205 } | 
| 227 | 206 | 
| 228 | 207 | 
| 229 static void ClearMarkbits() { | 208 static void ClearMarkbits() { | 
| 230   // TODO(gc): Clean the mark bits while sweeping. | 209   // TODO(gc): Clean the mark bits while sweeping. | 
| 231   ClearMarkbits(HEAP->code_space()); | 210   ClearMarkbits(HEAP->code_space()); | 
| 232   ClearMarkbits(HEAP->map_space()); | 211   ClearMarkbits(HEAP->map_space()); | 
| 233   ClearMarkbits(HEAP->old_pointer_space()); | 212   ClearMarkbits(HEAP->old_pointer_space()); | 
| 234   ClearMarkbits(HEAP->old_data_space()); | 213   ClearMarkbits(HEAP->old_data_space()); | 
| 235   ClearMarkbits(HEAP->cell_space()); | 214   ClearMarkbits(HEAP->cell_space()); | 
|  | 215   HEAP->new_space()->ActivePage()->markbits()->Clear(); | 
| 236 } | 216 } | 
| 237 | 217 | 
| 238 | 218 | 
| 239 void Marking::TransferMark(Address old_start, Address new_start) { | 219 void Marking::TransferMark(Address old_start, Address new_start) { | 
| 240   if (old_start == new_start) return; | 220   if (old_start == new_start) return; | 
| 241 | 221 | 
| 242   MarkBit new_mark_bit = MarkBitFrom(new_start); | 222   MarkBit new_mark_bit = MarkBitFrom(new_start); | 
| 243 | 223 | 
| 244   if (heap_->incremental_marking()->IsMarking()) { | 224   if (heap_->incremental_marking()->IsMarking()) { | 
| 245     MarkBit old_mark_bit = MarkBitFrom(old_start); | 225     MarkBit old_mark_bit = MarkBitFrom(old_start); | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 305   } | 285   } | 
| 306 #endif | 286 #endif | 
| 307 | 287 | 
| 308   PagedSpaces spaces; | 288   PagedSpaces spaces; | 
| 309   for (PagedSpace* space = spaces.next(); | 289   for (PagedSpace* space = spaces.next(); | 
| 310        space != NULL; space = spaces.next()) { | 290        space != NULL; space = spaces.next()) { | 
| 311     space->PrepareForMarkCompact(compacting_collection_); | 291     space->PrepareForMarkCompact(compacting_collection_); | 
| 312   } | 292   } | 
| 313 | 293 | 
| 314   if (!heap()->incremental_marking()->IsMarking()) { | 294   if (!heap()->incremental_marking()->IsMarking()) { | 
| 315     Address new_space_bottom = heap()->new_space()->bottom(); |  | 
| 316     uintptr_t new_space_size = |  | 
| 317         RoundUp(heap()->new_space()->top() - new_space_bottom, |  | 
| 318                 32 * kPointerSize); |  | 
| 319 |  | 
| 320     heap()->marking()->ClearRange(new_space_bottom, new_space_size); |  | 
| 321 |  | 
| 322     ClearMarkbits(); | 295     ClearMarkbits(); | 
| 323 #ifdef DEBUG | 296 #ifdef DEBUG | 
| 324     VerifyMarkbitsAreClean(); | 297     VerifyMarkbitsAreClean(); | 
| 325 #endif | 298 #endif | 
| 326   } | 299   } | 
| 327 | 300 | 
| 328 #ifdef DEBUG | 301 #ifdef DEBUG | 
| 329   live_bytes_ = 0; | 302   live_bytes_ = 0; | 
| 330   live_young_objects_size_ = 0; | 303   live_young_objects_size_ = 0; | 
| 331   live_old_pointer_objects_size_ = 0; | 304   live_old_pointer_objects_size_ = 0; | 
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 436     Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); | 409     Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); | 
| 437 | 410 | 
| 438     JSFunction* candidate = jsfunction_candidates_head_; | 411     JSFunction* candidate = jsfunction_candidates_head_; | 
| 439     JSFunction* next_candidate; | 412     JSFunction* next_candidate; | 
| 440     while (candidate != NULL) { | 413     while (candidate != NULL) { | 
| 441       next_candidate = GetNextCandidate(candidate); | 414       next_candidate = GetNextCandidate(candidate); | 
| 442 | 415 | 
| 443       SharedFunctionInfo* shared = candidate->unchecked_shared(); | 416       SharedFunctionInfo* shared = candidate->unchecked_shared(); | 
| 444 | 417 | 
| 445       Code* code = shared->unchecked_code(); | 418       Code* code = shared->unchecked_code(); | 
| 446       MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 419       MarkBit code_mark = Marking::MarkBitFrom(code); | 
| 447       if (!code_mark.Get()) { | 420       if (!code_mark.Get()) { | 
| 448         shared->set_code(lazy_compile); | 421         shared->set_code(lazy_compile); | 
| 449         candidate->set_code(lazy_compile); | 422         candidate->set_code(lazy_compile); | 
| 450       } else { | 423       } else { | 
| 451         candidate->set_code(shared->unchecked_code()); | 424         candidate->set_code(shared->unchecked_code()); | 
| 452       } | 425       } | 
| 453 | 426 | 
| 454       candidate = next_candidate; | 427       candidate = next_candidate; | 
| 455     } | 428     } | 
| 456 | 429 | 
| 457     jsfunction_candidates_head_ = NULL; | 430     jsfunction_candidates_head_ = NULL; | 
| 458   } | 431   } | 
| 459 | 432 | 
| 460 | 433 | 
| 461   void ProcessSharedFunctionInfoCandidates() { | 434   void ProcessSharedFunctionInfoCandidates() { | 
| 462     Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); | 435     Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); | 
| 463 | 436 | 
| 464     SharedFunctionInfo* candidate = shared_function_info_candidates_head_; | 437     SharedFunctionInfo* candidate = shared_function_info_candidates_head_; | 
| 465     SharedFunctionInfo* next_candidate; | 438     SharedFunctionInfo* next_candidate; | 
| 466     while (candidate != NULL) { | 439     while (candidate != NULL) { | 
| 467       next_candidate = GetNextCandidate(candidate); | 440       next_candidate = GetNextCandidate(candidate); | 
| 468       SetNextCandidate(candidate, NULL); | 441       SetNextCandidate(candidate, NULL); | 
| 469 | 442 | 
| 470       Code* code = candidate->unchecked_code(); | 443       Code* code = candidate->unchecked_code(); | 
| 471       MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 444       MarkBit code_mark = Marking::MarkBitFrom(code); | 
| 472       if (!code_mark.Get()) { | 445       if (!code_mark.Get()) { | 
| 473         candidate->set_code(lazy_compile); | 446         candidate->set_code(lazy_compile); | 
| 474       } | 447       } | 
| 475 | 448 | 
| 476       candidate = next_candidate; | 449       candidate = next_candidate; | 
| 477     } | 450     } | 
| 478 | 451 | 
| 479     shared_function_info_candidates_head_ = NULL; | 452     shared_function_info_candidates_head_ = NULL; | 
| 480   } | 453   } | 
| 481 | 454 | 
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 646   } | 619   } | 
| 647 | 620 | 
| 648   static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { | 621   static inline void VisitCodeTarget(Heap* heap, RelocInfo* rinfo) { | 
| 649     ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 622     ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 
| 650     Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 623     Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 
| 651     if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { | 624     if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { | 
| 652       IC::Clear(rinfo->pc()); | 625       IC::Clear(rinfo->pc()); | 
| 653       // Please note targets for cleared inline cached do not have to be | 626       // Please note targets for cleared inline cached do not have to be | 
| 654       // marked since they are contained in HEAP->non_monomorphic_cache(). | 627       // marked since they are contained in HEAP->non_monomorphic_cache(). | 
| 655     } else { | 628     } else { | 
| 656       MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 629       MarkBit code_mark = Marking::MarkBitFrom(code); | 
| 657       heap->mark_compact_collector()->MarkObject(code, code_mark); | 630       heap->mark_compact_collector()->MarkObject(code, code_mark); | 
| 658     } | 631     } | 
| 659   } | 632   } | 
| 660 | 633 | 
| 661   static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) { | 634   static void VisitGlobalPropertyCell(Heap* heap, RelocInfo* rinfo) { | 
| 662     ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); | 635     ASSERT(rinfo->rmode() == RelocInfo::GLOBAL_PROPERTY_CELL); | 
| 663     Object* cell = rinfo->target_cell(); | 636     Object* cell = rinfo->target_cell(); | 
| 664     Object* old_cell = cell; | 637     Object* old_cell = cell; | 
| 665     VisitPointer(heap, &cell); | 638     VisitPointer(heap, &cell); | 
| 666     if (cell != old_cell) { | 639     if (cell != old_cell) { | 
| 667       rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell), | 640       rinfo->set_target_cell(reinterpret_cast<JSGlobalPropertyCell*>(cell), | 
| 668                              NULL); | 641                              NULL); | 
| 669     } | 642     } | 
| 670   } | 643   } | 
| 671 | 644 | 
| 672   static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) { | 645   static inline void VisitDebugTarget(Heap* heap, RelocInfo* rinfo) { | 
| 673     ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 646     ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 
| 674             rinfo->IsPatchedReturnSequence()) || | 647             rinfo->IsPatchedReturnSequence()) || | 
| 675            (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 648            (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 
| 676             rinfo->IsPatchedDebugBreakSlotSequence())); | 649             rinfo->IsPatchedDebugBreakSlotSequence())); | 
| 677     HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 650     HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 
| 678     MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 651     MarkBit code_mark = Marking::MarkBitFrom(code); | 
| 679     heap->mark_compact_collector()->MarkObject(code, code_mark); | 652     heap->mark_compact_collector()->MarkObject(code, code_mark); | 
| 680   } | 653   } | 
| 681 | 654 | 
| 682   // Mark object pointed to by p. | 655   // Mark object pointed to by p. | 
| 683   INLINE(static void MarkObjectByPointer(Heap* heap, Object** p)) { | 656   INLINE(static void MarkObjectByPointer(Heap* heap, Object** p)) { | 
| 684     if (!(*p)->IsHeapObject()) return; | 657     if (!(*p)->IsHeapObject()) return; | 
| 685     HeapObject* object = ShortCircuitConsString(p); | 658     HeapObject* object = ShortCircuitConsString(p); | 
| 686     MarkBit mark = heap->marking()->MarkBitFrom(object); | 659     MarkBit mark = heap->marking()->MarkBitFrom(object); | 
| 687     heap->mark_compact_collector()->MarkObject(object, mark); | 660     heap->mark_compact_collector()->MarkObject(object, mark); | 
| 688   } | 661   } | 
| 689 | 662 | 
| 690 | 663 | 
| 691   // Visit an unmarked object. | 664   // Visit an unmarked object. | 
| 692   INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, | 665   INLINE(static void VisitUnmarkedObject(MarkCompactCollector* collector, | 
| 693                                          HeapObject* obj)) { | 666                                          HeapObject* obj)) { | 
| 694 #ifdef DEBUG | 667 #ifdef DEBUG | 
| 695     ASSERT(Isolate::Current()->heap()->Contains(obj)); | 668     ASSERT(Isolate::Current()->heap()->Contains(obj)); | 
| 696     ASSERT(!HEAP->mark_compact_collector()->IsMarked(obj)); | 669     ASSERT(!HEAP->mark_compact_collector()->IsMarked(obj)); | 
| 697 #endif | 670 #endif | 
| 698     Map* map = obj->map(); | 671     Map* map = obj->map(); | 
| 699     Heap* heap = obj->GetHeap(); | 672     Heap* heap = obj->GetHeap(); | 
| 700     // TODO(gc) ISOLATES MERGE | 673     // TODO(gc) ISOLATES MERGE | 
| 701     MarkBit mark = heap->marking()->MarkBitFrom(obj); | 674     MarkBit mark = heap->marking()->MarkBitFrom(obj); | 
| 702     heap->mark_compact_collector()->SetMark(obj, mark); | 675     heap->mark_compact_collector()->SetMark(obj, mark); | 
| 703     // Mark the map pointer and the body. | 676     // Mark the map pointer and the body. | 
| 704     MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 677     MarkBit map_mark = Marking::MarkBitFrom(map); | 
| 705     heap->mark_compact_collector()->MarkObject(map, map_mark); | 678     heap->mark_compact_collector()->MarkObject(map, map_mark); | 
| 706     IterateBody(map, obj); | 679     IterateBody(map, obj); | 
| 707   } | 680   } | 
| 708 | 681 | 
| 709   // Visit all unmarked objects pointed to by [start, end). | 682   // Visit all unmarked objects pointed to by [start, end). | 
| 710   // Returns false if the operation fails (lack of stack space). | 683   // Returns false if the operation fails (lack of stack space). | 
| 711   static inline bool VisitUnmarkedObjects(Heap* heap, | 684   static inline bool VisitUnmarkedObjects(Heap* heap, | 
| 712                                           Object** start, | 685                                           Object** start, | 
| 713                                           Object** end) { | 686                                           Object** end) { | 
| 714     // Return false is we are close to the stack limit. | 687     // Return false is we are close to the stack limit. | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 777     return function->unchecked_code() != | 750     return function->unchecked_code() != | 
| 778         function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); | 751         function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); | 
| 779   } | 752   } | 
| 780 | 753 | 
| 781   inline static bool IsFlushable(Heap* heap, JSFunction* function) { | 754   inline static bool IsFlushable(Heap* heap, JSFunction* function) { | 
| 782     SharedFunctionInfo* shared_info = function->unchecked_shared(); | 755     SharedFunctionInfo* shared_info = function->unchecked_shared(); | 
| 783 | 756 | 
| 784     // Code is either on stack, in compilation cache or referenced | 757     // Code is either on stack, in compilation cache or referenced | 
| 785     // by optimized version of function. | 758     // by optimized version of function. | 
| 786     MarkBit code_mark = | 759     MarkBit code_mark = | 
| 787         Marking::MarkBitFromOldSpace(function->unchecked_code()); | 760         Marking::MarkBitFrom(function->unchecked_code()); | 
| 788     if (code_mark.Get()) { | 761     if (code_mark.Get()) { | 
| 789       shared_info->set_code_age(0); | 762       shared_info->set_code_age(0); | 
| 790       return false; | 763       return false; | 
| 791     } | 764     } | 
| 792 | 765 | 
| 793     // We do not flush code for optimized functions. | 766     // We do not flush code for optimized functions. | 
| 794     if (function->code() != shared_info->unchecked_code()) { | 767     if (function->code() != shared_info->unchecked_code()) { | 
| 795       return false; | 768       return false; | 
| 796     } | 769     } | 
| 797 | 770 | 
| 798     return IsFlushable(heap, shared_info); | 771     return IsFlushable(heap, shared_info); | 
| 799   } | 772   } | 
| 800 | 773 | 
| 801   inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) { | 774   inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) { | 
| 802     // Code is either on stack, in compilation cache or referenced | 775     // Code is either on stack, in compilation cache or referenced | 
| 803     // by optimized version of function. | 776     // by optimized version of function. | 
| 804     MarkBit code_mark = | 777     MarkBit code_mark = | 
| 805         Marking::MarkBitFromOldSpace(shared_info->unchecked_code()); | 778         Marking::MarkBitFrom(shared_info->unchecked_code()); | 
| 806     if (code_mark.Get()) { | 779     if (code_mark.Get()) { | 
| 807       shared_info->set_code_age(0); | 780       shared_info->set_code_age(0); | 
| 808       return false; | 781       return false; | 
| 809     } | 782     } | 
| 810 | 783 | 
| 811     // The function must be compiled and have the source code available, | 784     // The function must be compiled and have the source code available, | 
| 812     // to be able to recompile it in case we need the function again. | 785     // to be able to recompile it in case we need the function again. | 
| 813     if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) { | 786     if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) { | 
| 814       return false; | 787       return false; | 
| 815     } | 788     } | 
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 947 | 920 | 
| 948     JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); | 921     JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); | 
| 949     // The function must have a valid context and not be a builtin. | 922     // The function must have a valid context and not be a builtin. | 
| 950     bool flush_code_candidate = false; | 923     bool flush_code_candidate = false; | 
| 951     if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { | 924     if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { | 
| 952       flush_code_candidate = FlushCodeForFunction(heap, jsfunction); | 925       flush_code_candidate = FlushCodeForFunction(heap, jsfunction); | 
| 953     } | 926     } | 
| 954 | 927 | 
| 955     if (!flush_code_candidate) { | 928     if (!flush_code_candidate) { | 
| 956       Code* code = jsfunction->unchecked_shared()->unchecked_code(); | 929       Code* code = jsfunction->unchecked_shared()->unchecked_code(); | 
| 957       MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 930       MarkBit code_mark = Marking::MarkBitFrom(code); | 
| 958       HEAP->mark_compact_collector()->MarkObject(code, code_mark); | 931       HEAP->mark_compact_collector()->MarkObject(code, code_mark); | 
| 959 | 932 | 
| 960       if (jsfunction->unchecked_code()->kind() == Code::OPTIMIZED_FUNCTION) { | 933       if (jsfunction->unchecked_code()->kind() == Code::OPTIMIZED_FUNCTION) { | 
| 961         // For optimized functions we should retain both non-optimized version | 934         // For optimized functions we should retain both non-optimized version | 
| 962         // of it's code and non-optimized version of all inlined functions. | 935         // of it's code and non-optimized version of all inlined functions. | 
| 963         // This is required to support bailing out from inlined code. | 936         // This is required to support bailing out from inlined code. | 
| 964         DeoptimizationInputData* data = | 937         DeoptimizationInputData* data = | 
| 965             reinterpret_cast<DeoptimizationInputData*>( | 938             reinterpret_cast<DeoptimizationInputData*>( | 
| 966                 jsfunction->unchecked_code()->unchecked_deoptimization_data()); | 939                 jsfunction->unchecked_code()->unchecked_deoptimization_data()); | 
| 967 | 940 | 
| 968         FixedArray* literals = data->UncheckedLiteralArray(); | 941         FixedArray* literals = data->UncheckedLiteralArray(); | 
| 969 | 942 | 
| 970         for (int i = 0, count = data->InlinedFunctionCount()->value(); | 943         for (int i = 0, count = data->InlinedFunctionCount()->value(); | 
| 971              i < count; | 944              i < count; | 
| 972              i++) { | 945              i++) { | 
| 973           JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i)); | 946           JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i)); | 
| 974           Code* inlined_code = inlined->unchecked_shared()->unchecked_code(); | 947           Code* inlined_code = inlined->unchecked_shared()->unchecked_code(); | 
| 975           MarkBit inlined_code_mark = | 948           MarkBit inlined_code_mark = | 
| 976               Marking::MarkBitFromOldSpace(inlined_code); | 949               Marking::MarkBitFrom(inlined_code); | 
| 977           HEAP->mark_compact_collector()->MarkObject( | 950           HEAP->mark_compact_collector()->MarkObject( | 
| 978               inlined_code, inlined_code_mark); | 951               inlined_code, inlined_code_mark); | 
| 979         } | 952         } | 
| 980       } | 953       } | 
| 981     } | 954     } | 
| 982 | 955 | 
| 983     VisitJSFunctionFields(map, | 956     VisitJSFunctionFields(map, | 
| 984                           reinterpret_cast<JSFunction*>(object), | 957                           reinterpret_cast<JSFunction*>(object), | 
| 985                           flush_code_candidate); | 958                           flush_code_candidate); | 
| 986   } | 959   } | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 1011     } else { | 984     } else { | 
| 1012       // Don't visit code object. | 985       // Don't visit code object. | 
| 1013 | 986 | 
| 1014       // Visit shared function info to avoid double checking of it's | 987       // Visit shared function info to avoid double checking of it's | 
| 1015       // flushability. | 988       // flushability. | 
| 1016       SharedFunctionInfo* shared_info = object->unchecked_shared(); | 989       SharedFunctionInfo* shared_info = object->unchecked_shared(); | 
| 1017       MarkBit shared_info_mark = heap->marking()->MarkBitFrom(shared_info); | 990       MarkBit shared_info_mark = heap->marking()->MarkBitFrom(shared_info); | 
| 1018       if (!shared_info_mark.Get()) { | 991       if (!shared_info_mark.Get()) { | 
| 1019         Map* shared_info_map = shared_info->map(); | 992         Map* shared_info_map = shared_info->map(); | 
| 1020         MarkBit shared_info_map_mark = | 993         MarkBit shared_info_map_mark = | 
| 1021             Marking::MarkBitFromOldSpace(shared_info_map); | 994             Marking::MarkBitFrom(shared_info_map); | 
| 1022         HEAP->mark_compact_collector()->SetMark(shared_info, shared_info_mark); | 995         HEAP->mark_compact_collector()->SetMark(shared_info, shared_info_mark); | 
| 1023         HEAP->mark_compact_collector()->MarkObject(shared_info_map, | 996         HEAP->mark_compact_collector()->MarkObject(shared_info_map, | 
| 1024                                                    shared_info_map_mark); | 997                                                    shared_info_map_mark); | 
| 1025         VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map, | 998         VisitSharedFunctionInfoAndFlushCodeGeneric(shared_info_map, | 
| 1026                                                    shared_info, | 999                                                    shared_info, | 
| 1027                                                    true); | 1000                                                    true); | 
| 1028       } | 1001       } | 
| 1029     } | 1002     } | 
| 1030 | 1003 | 
| 1031     VisitPointers(heap, | 1004     VisitPointers(heap, | 
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1093 | 1066 | 
| 1094 | 1067 | 
| 1095 class CodeMarkingVisitor : public ThreadVisitor { | 1068 class CodeMarkingVisitor : public ThreadVisitor { | 
| 1096  public: | 1069  public: | 
| 1097   explicit CodeMarkingVisitor(MarkCompactCollector* collector) | 1070   explicit CodeMarkingVisitor(MarkCompactCollector* collector) | 
| 1098       : collector_(collector) {} | 1071       : collector_(collector) {} | 
| 1099 | 1072 | 
| 1100   void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 1073   void VisitThread(Isolate* isolate, ThreadLocalTop* top) { | 
| 1101     for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 1074     for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { | 
| 1102       Code* code = it.frame()->unchecked_code(); | 1075       Code* code = it.frame()->unchecked_code(); | 
| 1103       MarkBit code_bit = Marking::MarkBitFromOldSpace(code); | 1076       MarkBit code_bit = Marking::MarkBitFrom(code); | 
| 1104       HEAP->mark_compact_collector()->MarkObject( | 1077       HEAP->mark_compact_collector()->MarkObject( | 
| 1105           it.frame()->unchecked_code(), code_bit); | 1078           it.frame()->unchecked_code(), code_bit); | 
| 1106     } | 1079     } | 
| 1107   } | 1080   } | 
| 1108 | 1081 | 
| 1109  private: | 1082  private: | 
| 1110   MarkCompactCollector* collector_; | 1083   MarkCompactCollector* collector_; | 
| 1111 }; | 1084 }; | 
| 1112 | 1085 | 
| 1113 | 1086 | 
| 1114 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { | 1087 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { | 
| 1115  public: | 1088  public: | 
| 1116   explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) | 1089   explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) | 
| 1117       : collector_(collector) {} | 1090       : collector_(collector) {} | 
| 1118 | 1091 | 
| 1119   void VisitPointers(Object** start, Object** end) { | 1092   void VisitPointers(Object** start, Object** end) { | 
| 1120     for (Object** p = start; p < end; p++) VisitPointer(p); | 1093     for (Object** p = start; p < end; p++) VisitPointer(p); | 
| 1121   } | 1094   } | 
| 1122 | 1095 | 
| 1123   void VisitPointer(Object** slot) { | 1096   void VisitPointer(Object** slot) { | 
| 1124     Object* obj = *slot; | 1097     Object* obj = *slot; | 
| 1125     if (obj->IsSharedFunctionInfo()) { | 1098     if (obj->IsSharedFunctionInfo()) { | 
| 1126       SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); | 1099       SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); | 
| 1127       // TODO(gc) ISOLATES MERGE | 1100       // TODO(gc) ISOLATES MERGE | 
| 1128       MarkBit shared_mark = HEAP->marking()->MarkBitFrom(shared); | 1101       MarkBit shared_mark = HEAP->marking()->MarkBitFrom(shared); | 
| 1129       MarkBit code_mark = | 1102       MarkBit code_mark = | 
| 1130           HEAP->marking()->MarkBitFromOldSpace(shared->unchecked_code()); | 1103           HEAP->marking()->MarkBitFrom(shared->unchecked_code()); | 
| 1131       HEAP->mark_compact_collector()->MarkObject(shared->unchecked_code(), | 1104       HEAP->mark_compact_collector()->MarkObject(shared->unchecked_code(), | 
| 1132                                                  code_mark); | 1105                                                  code_mark); | 
| 1133       HEAP->mark_compact_collector()->MarkObject(shared, shared_mark); | 1106       HEAP->mark_compact_collector()->MarkObject(shared, shared_mark); | 
| 1134     } | 1107     } | 
| 1135   } | 1108   } | 
| 1136 | 1109 | 
| 1137  private: | 1110  private: | 
| 1138   MarkCompactCollector* collector_; | 1111   MarkCompactCollector* collector_; | 
| 1139 }; | 1112 }; | 
| 1140 | 1113 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 1161   HeapObject* descriptor_array = heap()->raw_unchecked_empty_descriptor_array(); | 1134   HeapObject* descriptor_array = heap()->raw_unchecked_empty_descriptor_array(); | 
| 1162   // TODO(gc) ISOLATES MERGE | 1135   // TODO(gc) ISOLATES MERGE | 
| 1163   MarkBit descriptor_array_mark = | 1136   MarkBit descriptor_array_mark = | 
| 1164       heap()->marking()->MarkBitFrom(descriptor_array); | 1137       heap()->marking()->MarkBitFrom(descriptor_array); | 
| 1165   MarkObject(descriptor_array, descriptor_array_mark); | 1138   MarkObject(descriptor_array, descriptor_array_mark); | 
| 1166 | 1139 | 
| 1167   // Make sure we are not referencing the code from the stack. | 1140   // Make sure we are not referencing the code from the stack. | 
| 1168   ASSERT(this == heap()->mark_compact_collector()); | 1141   ASSERT(this == heap()->mark_compact_collector()); | 
| 1169   for (StackFrameIterator it; !it.done(); it.Advance()) { | 1142   for (StackFrameIterator it; !it.done(); it.Advance()) { | 
| 1170     Code* code = it.frame()->unchecked_code(); | 1143     Code* code = it.frame()->unchecked_code(); | 
| 1171     MarkBit code_mark = Marking::MarkBitFromOldSpace(code); | 1144     MarkBit code_mark = Marking::MarkBitFrom(code); | 
| 1172     MarkObject(code, code_mark); | 1145     MarkObject(code, code_mark); | 
| 1173   } | 1146   } | 
| 1174 | 1147 | 
| 1175   // Iterate the archived stacks in all threads to check if | 1148   // Iterate the archived stacks in all threads to check if | 
| 1176   // the code is referenced. | 1149   // the code is referenced. | 
| 1177   CodeMarkingVisitor code_marking_visitor(this); | 1150   CodeMarkingVisitor code_marking_visitor(this); | 
| 1178   heap()->isolate()->thread_manager()->IterateArchivedThreads( | 1151   heap()->isolate()->thread_manager()->IterateArchivedThreads( | 
| 1179       &code_marking_visitor); | 1152       &code_marking_visitor); | 
| 1180 | 1153 | 
| 1181   SharedFunctionInfoMarkingVisitor visitor(this); | 1154   SharedFunctionInfoMarkingVisitor visitor(this); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 1208     HeapObject* object = ShortCircuitConsString(p); | 1181     HeapObject* object = ShortCircuitConsString(p); | 
| 1209     // TODO(gc) ISOLATES MERGE | 1182     // TODO(gc) ISOLATES MERGE | 
| 1210     MarkBit mark_bit = HEAP->marking()->MarkBitFrom(object); | 1183     MarkBit mark_bit = HEAP->marking()->MarkBitFrom(object); | 
| 1211     if (mark_bit.Get()) return; | 1184     if (mark_bit.Get()) return; | 
| 1212 | 1185 | 
| 1213     Map* map = object->map(); | 1186     Map* map = object->map(); | 
| 1214     // Mark the object. | 1187     // Mark the object. | 
| 1215     HEAP->mark_compact_collector()->SetMark(object, mark_bit); | 1188     HEAP->mark_compact_collector()->SetMark(object, mark_bit); | 
| 1216 | 1189 | 
| 1217     // Mark the map pointer and body, and push them on the marking stack. | 1190     // Mark the map pointer and body, and push them on the marking stack. | 
| 1218     MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 1191     MarkBit map_mark = Marking::MarkBitFrom(map); | 
| 1219     HEAP->mark_compact_collector()->MarkObject(map, map_mark); | 1192     HEAP->mark_compact_collector()->MarkObject(map, map_mark); | 
| 1220     StaticMarkingVisitor::IterateBody(map, object); | 1193     StaticMarkingVisitor::IterateBody(map, object); | 
| 1221 | 1194 | 
| 1222     // Mark all the objects reachable from the map and body.  May leave | 1195     // Mark all the objects reachable from the map and body.  May leave | 
| 1223     // overflowed objects in the heap. | 1196     // overflowed objects in the heap. | 
| 1224     collector_->EmptyMarkingDeque(); | 1197     collector_->EmptyMarkingDeque(); | 
| 1225   } | 1198   } | 
| 1226 | 1199 | 
| 1227   MarkCompactCollector* collector_; | 1200   MarkCompactCollector* collector_; | 
| 1228 }; | 1201 }; | 
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1544 // marking stack have been marked, or are overflowed in the heap. | 1517 // marking stack have been marked, or are overflowed in the heap. | 
| 1545 void MarkCompactCollector::EmptyMarkingDeque() { | 1518 void MarkCompactCollector::EmptyMarkingDeque() { | 
| 1546   while (!marking_deque_.IsEmpty()) { | 1519   while (!marking_deque_.IsEmpty()) { | 
| 1547     HeapObject* object = marking_deque_.Pop(); | 1520     HeapObject* object = marking_deque_.Pop(); | 
| 1548     ASSERT(object->IsHeapObject()); | 1521     ASSERT(object->IsHeapObject()); | 
| 1549     ASSERT(heap()->Contains(object)); | 1522     ASSERT(heap()->Contains(object)); | 
| 1550     ASSERT(IsMarked(object)); | 1523     ASSERT(IsMarked(object)); | 
| 1551     ASSERT(!object->IsOverflowed()); | 1524     ASSERT(!object->IsOverflowed()); | 
| 1552 | 1525 | 
| 1553     Map* map = object->map(); | 1526     Map* map = object->map(); | 
| 1554     MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 1527     MarkBit map_mark = Marking::MarkBitFrom(map); | 
| 1555     MarkObject(map, map_mark); | 1528     MarkObject(map, map_mark); | 
| 1556 | 1529 | 
| 1557     StaticMarkingVisitor::IterateBody(map, object); | 1530     StaticMarkingVisitor::IterateBody(map, object); | 
| 1558   } | 1531   } | 
| 1559 } | 1532 } | 
| 1560 | 1533 | 
| 1561 | 1534 | 
| 1562 // Sweep the heap for overflowed objects, clear their overflow bits, and | 1535 // Sweep the heap for overflowed objects, clear their overflow bits, and | 
| 1563 // push them on the marking stack.  Stop early if the marking stack fills | 1536 // push them on the marking stack.  Stop early if the marking stack fills | 
| 1564 // before sweeping completes.  If sweeping completes, there are no remaining | 1537 // before sweeping completes.  If sweeping completes, there are no remaining | 
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1749   // dropping the back pointers temporarily stored in the prototype field. | 1722   // dropping the back pointers temporarily stored in the prototype field. | 
| 1750   // Setting the prototype field requires following the linked list of | 1723   // Setting the prototype field requires following the linked list of | 
| 1751   // back pointers, reversing them all at once.  This allows us to find | 1724   // back pointers, reversing them all at once.  This allows us to find | 
| 1752   // those maps with map transitions that need to be nulled, and only | 1725   // those maps with map transitions that need to be nulled, and only | 
| 1753   // scan the descriptor arrays of those maps, not all maps. | 1726   // scan the descriptor arrays of those maps, not all maps. | 
| 1754   // All of these actions are carried out only on maps of JSObjects | 1727   // All of these actions are carried out only on maps of JSObjects | 
| 1755   // and related subtypes. | 1728   // and related subtypes. | 
| 1756   for (HeapObject* obj = map_iterator.Next(); | 1729   for (HeapObject* obj = map_iterator.Next(); | 
| 1757        obj != NULL; obj = map_iterator.Next()) { | 1730        obj != NULL; obj = map_iterator.Next()) { | 
| 1758     Map* map = reinterpret_cast<Map*>(obj); | 1731     Map* map = reinterpret_cast<Map*>(obj); | 
| 1759     MarkBit map_mark = Marking::MarkBitFromOldSpace(map); | 1732     MarkBit map_mark = Marking::MarkBitFrom(map); | 
| 1760     if (map->IsFreeSpace()) continue; | 1733     if (map->IsFreeSpace()) continue; | 
| 1761 | 1734 | 
| 1762     ASSERT(SafeIsMap(map)); | 1735     ASSERT(SafeIsMap(map)); | 
| 1763     // Only JSObject and subtypes have map transitions and back pointers. | 1736     // Only JSObject and subtypes have map transitions and back pointers. | 
| 1764     if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; | 1737     if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue; | 
| 1765     if (map->instance_type() > JS_FUNCTION_TYPE) continue; | 1738     if (map->instance_type() > JS_FUNCTION_TYPE) continue; | 
| 1766 | 1739 | 
| 1767     if (map_mark.Get() && | 1740     if (map_mark.Get() && | 
| 1768         map->attached_to_shared_function_info()) { | 1741         map->attached_to_shared_function_info()) { | 
| 1769       // This map is used for inobject slack tracking and has been detached | 1742       // This map is used for inobject slack tracking and has been detached | 
| 1770       // from SharedFunctionInfo during the mark phase. | 1743       // from SharedFunctionInfo during the mark phase. | 
| 1771       // Since it survived the GC, reattach it now. | 1744       // Since it survived the GC, reattach it now. | 
| 1772       map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); | 1745       map->unchecked_constructor()->unchecked_shared()->AttachInitialMap(map); | 
| 1773     } | 1746     } | 
| 1774 | 1747 | 
| 1775     // Clear dead prototype transitions. | 1748     // Clear dead prototype transitions. | 
| 1776     FixedArray* prototype_transitions = map->unchecked_prototype_transitions(); | 1749     FixedArray* prototype_transitions = map->unchecked_prototype_transitions(); | 
| 1777     if (prototype_transitions->length() > 0) { | 1750     if (prototype_transitions->length() > 0) { | 
| 1778       int finger = Smi::cast(prototype_transitions->get(0))->value(); | 1751       int finger = Smi::cast(prototype_transitions->get(0))->value(); | 
| 1779       int new_finger = 1; | 1752       int new_finger = 1; | 
| 1780       for (int i = 1; i < finger; i += 2) { | 1753       for (int i = 1; i < finger; i += 2) { | 
| 1781         HeapObject* prototype = HeapObject::cast(prototype_transitions->get(i)); | 1754         HeapObject* prototype = HeapObject::cast(prototype_transitions->get(i)); | 
| 1782         Map* cached_map = Map::cast(prototype_transitions->get(i + 1)); | 1755         Map* cached_map = Map::cast(prototype_transitions->get(i + 1)); | 
| 1783         MarkBit prototype_mark = heap()->marking()->MarkBitFrom(prototype); | 1756         MarkBit prototype_mark = heap()->marking()->MarkBitFrom(prototype); | 
| 1784         MarkBit cached_map_mark = Marking::MarkBitFromOldSpace(cached_map); | 1757         MarkBit cached_map_mark = Marking::MarkBitFrom(cached_map); | 
| 1785         if (prototype_mark.Get() && cached_map_mark.Get()) { | 1758         if (prototype_mark.Get() && cached_map_mark.Get()) { | 
| 1786           if (new_finger != i) { | 1759           if (new_finger != i) { | 
| 1787             prototype_transitions->set_unchecked(heap_, | 1760             prototype_transitions->set_unchecked(heap_, | 
| 1788                                                  new_finger, | 1761                                                  new_finger, | 
| 1789                                                  prototype, | 1762                                                  prototype, | 
| 1790                                                  UPDATE_WRITE_BARRIER); | 1763                                                  UPDATE_WRITE_BARRIER); | 
| 1791             prototype_transitions->set_unchecked(heap_, | 1764             prototype_transitions->set_unchecked(heap_, | 
| 1792                                                  new_finger + 1, | 1765                                                  new_finger + 1, | 
| 1793                                                  cached_map, | 1766                                                  cached_map, | 
| 1794                                                  SKIP_WRITE_BARRIER); | 1767                                                  SKIP_WRITE_BARRIER); | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 1817     Object* real_prototype = current; | 1790     Object* real_prototype = current; | 
| 1818 | 1791 | 
| 1819     // Follow back pointers, setting them to prototype, | 1792     // Follow back pointers, setting them to prototype, | 
| 1820     // clearing map transitions when necessary. | 1793     // clearing map transitions when necessary. | 
| 1821     current = map; | 1794     current = map; | 
| 1822     bool on_dead_path = !map_mark.Get(); | 1795     bool on_dead_path = !map_mark.Get(); | 
| 1823     Object* next; | 1796     Object* next; | 
| 1824     while (SafeIsMap(current)) { | 1797     while (SafeIsMap(current)) { | 
| 1825       next = current->prototype(); | 1798       next = current->prototype(); | 
| 1826       // There should never be a dead map above a live map. | 1799       // There should never be a dead map above a live map. | 
| 1827       MarkBit current_mark = Marking::MarkBitFromOldSpace(current); | 1800       MarkBit current_mark = Marking::MarkBitFrom(current); | 
| 1828       ASSERT(on_dead_path || current_mark.Get()); | 1801       ASSERT(on_dead_path || current_mark.Get()); | 
| 1829 | 1802 | 
| 1830       // A live map above a dead map indicates a dead transition. | 1803       // A live map above a dead map indicates a dead transition. | 
| 1831       // This test will always be false on the first iteration. | 1804       // This test will always be false on the first iteration. | 
| 1832       if (on_dead_path && current_mark.Get()) { | 1805       if (on_dead_path && current_mark.Get()) { | 
| 1833         on_dead_path = false; | 1806         on_dead_path = false; | 
| 1834         current->ClearNonLiveTransitions(heap(), real_prototype); | 1807         current->ClearNonLiveTransitions(heap(), real_prototype); | 
| 1835       } | 1808       } | 
| 1836       *HeapObject::RawField(current, Map::kPrototypeOffset) = | 1809       *HeapObject::RawField(current, Map::kPrototypeOffset) = | 
| 1837           real_prototype; | 1810           real_prototype; | 
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2010   int survivors_size = 0; | 1983   int survivors_size = 0; | 
| 2011 | 1984 | 
| 2012   // First pass: traverse all objects in inactive semispace, remove marks, | 1985   // First pass: traverse all objects in inactive semispace, remove marks, | 
| 2013   // migrate live objects and write forwarding addresses.  This stage puts | 1986   // migrate live objects and write forwarding addresses.  This stage puts | 
| 2014   // new entries in the store buffer and may cause some pages to be marked | 1987   // new entries in the store buffer and may cause some pages to be marked | 
| 2015   // scan-on-scavenge. | 1988   // scan-on-scavenge. | 
| 2016   for (Address current = from_bottom; current < from_top; current += size) { | 1989   for (Address current = from_bottom; current < from_top; current += size) { | 
| 2017     HeapObject* object = HeapObject::FromAddress(current); | 1990     HeapObject* object = HeapObject::FromAddress(current); | 
| 2018 | 1991 | 
| 2019 | 1992 | 
| 2020     MarkBit mark_bit = heap_->marking()->MarkBitFromNewSpace(object); | 1993     MarkBit mark_bit = heap_->marking()->MarkBitFrom(object); | 
| 2021     if (mark_bit.Get()) { | 1994     if (mark_bit.Get()) { | 
| 2022       mark_bit.Clear(); | 1995       mark_bit.Clear(); | 
| 2023       heap_->mark_compact_collector()->tracer()->decrement_marked_count(); | 1996       heap_->mark_compact_collector()->tracer()->decrement_marked_count(); | 
| 2024 | 1997 | 
| 2025       size = object->Size(); | 1998       size = object->Size(); | 
| 2026       survivors_size += size; | 1999       survivors_size += size; | 
| 2027 | 2000 | 
| 2028       // Aggressively promote young survivors to the old space. | 2001       // Aggressively promote young survivors to the old space. | 
| 2029       if (TryPromoteObject(heap_, object, size)) { | 2002       if (TryPromoteObject(heap_, object, size)) { | 
| 2030         continue; | 2003         continue; | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2106                                  uint32_t free_start, | 2079                                  uint32_t free_start, | 
| 2107                                  uint32_t region_end, | 2080                                  uint32_t region_end, | 
| 2108                                  uint32_t* cells)); | 2081                                  uint32_t* cells)); | 
| 2109 | 2082 | 
| 2110 | 2083 | 
| 2111 static uint32_t SweepFree(PagedSpace* space, | 2084 static uint32_t SweepFree(PagedSpace* space, | 
| 2112                           Page* p, | 2085                           Page* p, | 
| 2113                           uint32_t free_start, | 2086                           uint32_t free_start, | 
| 2114                           uint32_t region_end, | 2087                           uint32_t region_end, | 
| 2115                           uint32_t* cells) { | 2088                           uint32_t* cells) { | 
| 2116   uint32_t free_cell_index = Page::MarkbitsBitmap::IndexToCell(free_start); | 2089   uint32_t free_cell_index = Bitmap::IndexToCell(free_start); | 
| 2117   ASSERT(cells[free_cell_index] == 0); | 2090   ASSERT(cells[free_cell_index] == 0); | 
| 2118   while (free_cell_index < region_end && cells[free_cell_index] == 0) { | 2091   while (free_cell_index < region_end && cells[free_cell_index] == 0) { | 
| 2119     free_cell_index++; | 2092     free_cell_index++; | 
| 2120   } | 2093   } | 
| 2121 | 2094 | 
| 2122   if (free_cell_index >= region_end) { | 2095   if (free_cell_index >= region_end) { | 
| 2123     return free_cell_index; | 2096     return free_cell_index; | 
| 2124   } | 2097   } | 
| 2125 | 2098 | 
| 2126   uint32_t free_end = Page::MarkbitsBitmap::CellToIndex(free_cell_index); | 2099   uint32_t free_end = Bitmap::CellToIndex(free_cell_index); | 
| 2127   space->Free(p->MarkbitIndexToAddress(free_start), | 2100   space->Free(p->MarkbitIndexToAddress(free_start), | 
| 2128               (free_end - free_start) << kPointerSizeLog2); | 2101               (free_end - free_start) << kPointerSizeLog2); | 
| 2129 | 2102 | 
| 2130   return free_cell_index; | 2103   return free_cell_index; | 
| 2131 } | 2104 } | 
| 2132 | 2105 | 
| 2133 | 2106 | 
| 2134 INLINE(static uint32_t NextCandidate(uint32_t cell_index, | 2107 INLINE(static uint32_t NextCandidate(uint32_t cell_index, | 
| 2135                                      uint32_t last_cell_index, | 2108                                      uint32_t last_cell_index, | 
| 2136                                      uint32_t* cells)); | 2109                                      uint32_t* cells)); | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 2154 static int SizeOfPreviousObject(Page* p, | 2127 static int SizeOfPreviousObject(Page* p, | 
| 2155                                 uint32_t cell_index, | 2128                                 uint32_t cell_index, | 
| 2156                                 uint32_t* cells) { | 2129                                 uint32_t* cells) { | 
| 2157   ASSERT(cells[cell_index] == 0); | 2130   ASSERT(cells[cell_index] == 0); | 
| 2158   if (cells[cell_index - 1] == 0) return 0; | 2131   if (cells[cell_index - 1] == 0) return 0; | 
| 2159 | 2132 | 
| 2160   int leading_zeroes = | 2133   int leading_zeroes = | 
| 2161       CompilerIntrinsics::CountLeadingZeros(cells[cell_index - 1]) + 1; | 2134       CompilerIntrinsics::CountLeadingZeros(cells[cell_index - 1]) + 1; | 
| 2162   Address addr = | 2135   Address addr = | 
| 2163       p->MarkbitIndexToAddress( | 2136       p->MarkbitIndexToAddress( | 
| 2164           Page::MarkbitsBitmap::CellToIndex(cell_index) - leading_zeroes); | 2137           Bitmap::CellToIndex(cell_index) - leading_zeroes); | 
| 2165   HeapObject* obj = HeapObject::FromAddress(addr); | 2138   HeapObject* obj = HeapObject::FromAddress(addr); | 
| 2166   ASSERT(obj->map()->IsMap()); | 2139   ASSERT(obj->map()->IsMap()); | 
| 2167   return (obj->Size() >> kPointerSizeLog2) - leading_zeroes; | 2140   return (obj->Size() >> kPointerSizeLog2) - leading_zeroes; | 
| 2168 } | 2141 } | 
| 2169 | 2142 | 
| 2170 | 2143 | 
| 2171 static const int kStartTableEntriesPerLine = 5; | 2144 static const int kStartTableEntriesPerLine = 5; | 
| 2172 static const int kStartTableLines = 171; | 2145 static const int kStartTableLines = 171; | 
| 2173 static const int kStartTableInvalidLine = 127; | 2146 static const int kStartTableInvalidLine = 127; | 
| 2174 static const int kStartTableUnusedEntry = 126; | 2147 static const int kStartTableUnusedEntry = 126; | 
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2449   int freed_bytes = 0; | 2422   int freed_bytes = 0; | 
| 2450 | 2423 | 
| 2451   MarkBit::CellType* cells = p->markbits()->cells(); | 2424   MarkBit::CellType* cells = p->markbits()->cells(); | 
| 2452 | 2425 | 
| 2453   p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); | 2426   p->SetFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); | 
| 2454 | 2427 | 
| 2455   // This is the start of the 32 word block that we are currently looking at. | 2428   // This is the start of the 32 word block that we are currently looking at. | 
| 2456   Address block_address = p->ObjectAreaStart(); | 2429   Address block_address = p->ObjectAreaStart(); | 
| 2457 | 2430 | 
| 2458   int last_cell_index = | 2431   int last_cell_index = | 
| 2459       Page::MarkbitsBitmap::IndexToCell( | 2432       Bitmap::IndexToCell( | 
| 2460           Page::MarkbitsBitmap::CellAlignIndex( | 2433           Bitmap::CellAlignIndex( | 
| 2461               p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); | 2434               p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); | 
| 2462 | 2435 | 
| 2463   int cell_index = Page::kFirstUsedCell; | 2436   int cell_index = Page::kFirstUsedCell; | 
| 2464 | 2437 | 
| 2465   // Skip over all the dead objects at the start of the page and mark them free. | 2438   // Skip over all the dead objects at the start of the page and mark them free. | 
| 2466   for (cell_index = Page::kFirstUsedCell; | 2439   for (cell_index = Page::kFirstUsedCell; | 
| 2467        cell_index < last_cell_index; | 2440        cell_index < last_cell_index; | 
| 2468        cell_index++, block_address += 32 * kPointerSize) { | 2441        cell_index++, block_address += 32 * kPointerSize) { | 
| 2469     if (cells[cell_index] != 0) break; | 2442     if (cells[cell_index] != 0) break; | 
| 2470   } | 2443   } | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 2485   // started.  Unless we find a large free space in the bitmap we will not | 2458   // started.  Unless we find a large free space in the bitmap we will not | 
| 2486   // digest this pair into a real address.  We start the iteration here at the | 2459   // digest this pair into a real address.  We start the iteration here at the | 
| 2487   // first word in the marking bit map that indicates a live object. | 2460   // first word in the marking bit map that indicates a live object. | 
| 2488   Address free_start = block_address; | 2461   Address free_start = block_address; | 
| 2489   uint32_t free_start_cell = cells[cell_index]; | 2462   uint32_t free_start_cell = cells[cell_index]; | 
| 2490 | 2463 | 
| 2491   for ( ; | 2464   for ( ; | 
| 2492        cell_index < last_cell_index; | 2465        cell_index < last_cell_index; | 
| 2493        cell_index++, block_address += 32 * kPointerSize) { | 2466        cell_index++, block_address += 32 * kPointerSize) { | 
| 2494     ASSERT((unsigned)cell_index == | 2467     ASSERT((unsigned)cell_index == | 
| 2495         Page::MarkbitsBitmap::IndexToCell( | 2468         Bitmap::IndexToCell( | 
| 2496             Page::MarkbitsBitmap::CellAlignIndex( | 2469             Bitmap::CellAlignIndex( | 
| 2497                 p->AddressToMarkbitIndex(block_address)))); | 2470                 p->AddressToMarkbitIndex(block_address)))); | 
| 2498     uint32_t cell = cells[cell_index]; | 2471     uint32_t cell = cells[cell_index]; | 
| 2499     if (cell != 0) { | 2472     if (cell != 0) { | 
| 2500       // We have a live object.  Check approximately whether it is more than 32 | 2473       // We have a live object.  Check approximately whether it is more than 32 | 
| 2501       // words since the last live object. | 2474       // words since the last live object. | 
| 2502       if (block_address - free_start > 32 * kPointerSize) { | 2475       if (block_address - free_start > 32 * kPointerSize) { | 
| 2503         free_start = DigestFreeStart(free_start, free_start_cell); | 2476         free_start = DigestFreeStart(free_start, free_start_cell); | 
| 2504         if (block_address - free_start > 32 * kPointerSize) { | 2477         if (block_address - free_start > 32 * kPointerSize) { | 
| 2505           // Now that we know the exact start of the free space it still looks | 2478           // Now that we know the exact start of the free space it still looks | 
| 2506           // like we have a large enough free space to be worth bothering with. | 2479           // like we have a large enough free space to be worth bothering with. | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 2530 // be iterated precisely, hitting only the live objects.  Code space | 2503 // be iterated precisely, hitting only the live objects.  Code space | 
| 2531 // is always swept precisely because we want to be able to iterate | 2504 // is always swept precisely because we want to be able to iterate | 
| 2532 // over it.  Map space is swept precisely, because it is not compacted. | 2505 // over it.  Map space is swept precisely, because it is not compacted. | 
| 2533 static void SweepPrecisely(PagedSpace* space, | 2506 static void SweepPrecisely(PagedSpace* space, | 
| 2534                            Page* p) { | 2507                            Page* p) { | 
| 2535   MarkBit::CellType* cells = p->markbits()->cells(); | 2508   MarkBit::CellType* cells = p->markbits()->cells(); | 
| 2536 | 2509 | 
| 2537   p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); | 2510   p->ClearFlag(MemoryChunk::WAS_SWEPT_CONSERVATIVELY); | 
| 2538 | 2511 | 
| 2539   int last_cell_index = | 2512   int last_cell_index = | 
| 2540       Page::MarkbitsBitmap::IndexToCell( | 2513       Bitmap::IndexToCell( | 
| 2541           Page::MarkbitsBitmap::CellAlignIndex( | 2514           Bitmap::CellAlignIndex( | 
| 2542               p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); | 2515               p->AddressToMarkbitIndex(p->ObjectAreaEnd()))); | 
| 2543 | 2516 | 
| 2544   int cell_index = Page::kFirstUsedCell; | 2517   int cell_index = Page::kFirstUsedCell; | 
| 2545   Address free_start = p->ObjectAreaStart(); | 2518   Address free_start = p->ObjectAreaStart(); | 
| 2546   ASSERT(reinterpret_cast<uint32_t>(free_start) % (32 * kPointerSize) == 0); | 2519   ASSERT(reinterpret_cast<uint32_t>(free_start) % (32 * kPointerSize) == 0); | 
| 2547   Address object_address = p->ObjectAreaStart(); | 2520   Address object_address = p->ObjectAreaStart(); | 
| 2548   int offsets[16]; | 2521   int offsets[16]; | 
| 2549 | 2522 | 
| 2550   for (cell_index = Page::kFirstUsedCell; | 2523   for (cell_index = Page::kFirstUsedCell; | 
| 2551        cell_index < last_cell_index; | 2524        cell_index < last_cell_index; | 
| 2552        cell_index++, object_address += 32 * kPointerSize) { | 2525        cell_index++, object_address += 32 * kPointerSize) { | 
| 2553     ASSERT((unsigned)cell_index == | 2526     ASSERT((unsigned)cell_index == | 
| 2554         Page::MarkbitsBitmap::IndexToCell( | 2527         Bitmap::IndexToCell( | 
| 2555             Page::MarkbitsBitmap::CellAlignIndex( | 2528             Bitmap::CellAlignIndex( | 
| 2556                 p->AddressToMarkbitIndex(object_address)))); | 2529                 p->AddressToMarkbitIndex(object_address)))); | 
| 2557     int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); | 2530     int live_objects = MarkWordToObjectStarts(cells[cell_index], offsets); | 
| 2558     int live_index = 0; | 2531     int live_index = 0; | 
| 2559     for ( ; live_objects != 0; live_objects--) { | 2532     for ( ; live_objects != 0; live_objects--) { | 
| 2560       Address free_end = object_address + offsets[live_index++] * kPointerSize; | 2533       Address free_end = object_address + offsets[live_index++] * kPointerSize; | 
| 2561       if (free_end != free_start) { | 2534       if (free_end != free_start) { | 
| 2562         space->Free(free_start, free_end - free_start); | 2535         space->Free(free_start, free_end - free_start); | 
| 2563       } | 2536       } | 
| 2564       HeapObject* live_object = HeapObject::FromAddress(free_end); | 2537       HeapObject* live_object = HeapObject::FromAddress(free_end); | 
| 2565       free_start = free_end + live_object->Size(); | 2538       free_start = free_end + live_object->Size(); | 
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2726 } | 2699 } | 
| 2727 | 2700 | 
| 2728 | 2701 | 
| 2729 void MarkCompactCollector::Initialize() { | 2702 void MarkCompactCollector::Initialize() { | 
| 2730   StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2703   StaticPointersToNewGenUpdatingVisitor::Initialize(); | 
| 2731   StaticMarkingVisitor::Initialize(); | 2704   StaticMarkingVisitor::Initialize(); | 
| 2732 } | 2705 } | 
| 2733 | 2706 | 
| 2734 | 2707 | 
| 2735 } }  // namespace v8::internal | 2708 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|