| Index: src/mark-compact.h
 | 
| diff --git a/src/mark-compact.h b/src/mark-compact.h
 | 
| index 6b5d4c9e182a4a5bfb1ba24fe101056db19a7182..5fd22f46a39126b963404028d5c09bf9a114de31 100644
 | 
| --- a/src/mark-compact.h
 | 
| +++ b/src/mark-compact.h
 | 
| @@ -295,7 +295,17 @@ class SlotsBuffer {
 | 
|      slots_[idx_++] = slot;
 | 
|    }
 | 
|  
 | 
| -  void UpdateSlots();
 | 
| +  enum SlotType {
 | 
| +    NONE,
 | 
| +    RELOCATED_CODE_OBJECT,
 | 
| +    CODE_TARGET_SLOT,
 | 
| +    CODE_ENTRY_SLOT,
 | 
| +    DEBUG_TARGET_SLOT,
 | 
| +    JS_RETURN_SLOT,
 | 
| +    NUMBER_OF_SLOT_TYPES
 | 
| +  };
 | 
| +
 | 
| +  SlotType UpdateSlots(Heap* heap, SlotType pending);
 | 
|  
 | 
|    SlotsBuffer* next() { return next_; }
 | 
|  
 | 
| @@ -309,9 +319,10 @@ class SlotsBuffer {
 | 
|      return idx_ == kNumberOfElements;
 | 
|    }
 | 
|  
 | 
| -  static void UpdateSlotsRecordedIn(SlotsBuffer* buffer) {
 | 
| +  static void UpdateSlotsRecordedIn(Heap* heap, SlotsBuffer* buffer) {
 | 
| +    SlotType pending = NONE;
 | 
|      while (buffer != NULL) {
 | 
| -      buffer->UpdateSlots();
 | 
| +      pending = buffer->UpdateSlots(heap, pending);
 | 
|        buffer = buffer->next();
 | 
|      }
 | 
|    }
 | 
| @@ -340,6 +351,14 @@ class SlotsBuffer {
 | 
|      return true;
 | 
|    }
 | 
|  
 | 
| +  static bool IsTypedSlot(ObjectSlot slot);
 | 
| +
 | 
| +  static bool AddTo(SlotsBufferAllocator* allocator,
 | 
| +                    SlotsBuffer** buffer_address,
 | 
| +                    SlotType type,
 | 
| +                    Address addr,
 | 
| +                    AdditionMode mode);
 | 
| +
 | 
|    static const int kNumberOfElements = 1021;
 | 
|  
 | 
|   private:
 | 
| @@ -455,40 +474,42 @@ class MarkCompactCollector {
 | 
|          ShouldSkipEvacuationSlotRecording();
 | 
|    }
 | 
|  
 | 
| +  INLINE(static bool ShouldSkipEvacuationSlotRecording(Object* host)) {
 | 
| +    return Page::FromAddress(reinterpret_cast<Address>(host))->
 | 
| +        ShouldSkipEvacuationSlotRecording();
 | 
| +  }
 | 
| +
 | 
|    INLINE(static bool IsOnEvacuationCandidate(Object* obj)) {
 | 
|      return Page::FromAddress(reinterpret_cast<Address>(obj))->
 | 
|          IsEvacuationCandidate();
 | 
|    }
 | 
|  
 | 
| -  INLINE(void RecordSlot(Object** anchor_slot, Object** slot, Object* object)) {
 | 
| -    Page* object_page = Page::FromAddress(reinterpret_cast<Address>(object));
 | 
| -    if (object_page->IsEvacuationCandidate() &&
 | 
| -        !ShouldSkipEvacuationSlotRecording(anchor_slot)) {
 | 
| -      if (!SlotsBuffer::AddTo(&slots_buffer_allocator_,
 | 
| -                              object_page->slots_buffer_address(),
 | 
| -                              slot,
 | 
| -                              SlotsBuffer::FAIL_ON_OVERFLOW)) {
 | 
| -        if (FLAG_trace_fragmentation) {
 | 
| -          PrintF("Page %p is too popular. Disabling evacuation.\n",
 | 
| -                 reinterpret_cast<void*>(object_page));
 | 
| -        }
 | 
| -        // TODO(gc) If all evacuation candidates are too popular we
 | 
| -        // should stop slots recording entirely.
 | 
| -        object_page->ClearEvacuationCandidate();
 | 
| -
 | 
| -        // We were not collecting slots on this page that point
 | 
| -        // to other evacuation candidates thus we have to
 | 
| -        // rescan the page after evacuation to discover and update all
 | 
| -        // pointers to evacuated objects.
 | 
| -        if (object_page->owner()->identity() == OLD_DATA_SPACE) {
 | 
| -          evacuation_candidates_.RemoveElement(object_page);
 | 
| -        } else {
 | 
| -          object_page->SetFlag(Page::RESCAN_ON_EVACUATION);
 | 
| -        }
 | 
| -      }
 | 
| +  void EvictEvacuationCandidate(Page* page) {
 | 
| +    if (FLAG_trace_fragmentation) {
 | 
| +      PrintF("Page %p is too popular. Disabling evacuation.\n",
 | 
| +             reinterpret_cast<void*>(page));
 | 
| +    }
 | 
| +
 | 
| +    // TODO(gc) If all evacuation candidates are too popular we
 | 
| +    // should stop slots recording entirely.
 | 
| +    page->ClearEvacuationCandidate();
 | 
| +
 | 
| +    // We were not collecting slots on this page that point
 | 
| +    // to other evacuation candidates thus we have to
 | 
| +    // rescan the page after evacuation to discover and update all
 | 
| +    // pointers to evacuated objects.
 | 
| +    if (page->owner()->identity() == OLD_DATA_SPACE) {
 | 
| +      evacuation_candidates_.RemoveElement(page);
 | 
| +    } else {
 | 
| +      page->SetFlag(Page::RESCAN_ON_EVACUATION);
 | 
|      }
 | 
|    }
 | 
|  
 | 
| +  void RecordRelocSlot(RelocInfo* rinfo, Code* target);
 | 
| +  void RecordCodeEntrySlot(Address slot, Code* target);
 | 
| +
 | 
| +  INLINE(void RecordSlot(Object** anchor_slot, Object** slot, Object* object));
 | 
| +
 | 
|    void MigrateObject(Address dst,
 | 
|                       Address src,
 | 
|                       int size,
 | 
| 
 |