| Index: src/heap/mark-compact.cc | 
| diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc | 
| index 44262e42b162b58974cf7b2092ea141047856d2a..8539596a62e5cfbd8f4c8850f929ade5e31f1d96 100644 | 
| --- a/src/heap/mark-compact.cc | 
| +++ b/src/heap/mark-compact.cc | 
| @@ -314,6 +314,14 @@ void MarkCompactCollector::CollectGarbage() { | 
| } | 
| #endif | 
|  | 
| +  heap_->store_buffer()->ClearInvalidStoreBufferEntries(); | 
| + | 
| +#ifdef VERIFY_HEAP | 
| +  if (FLAG_verify_heap) { | 
| +    heap_->store_buffer()->VerifyValidStoreBufferEntries(); | 
| +  } | 
| +#endif | 
| + | 
| SweepSpaces(); | 
|  | 
| #ifdef VERIFY_HEAP | 
| @@ -3048,6 +3056,137 @@ bool MarkCompactCollector::TryPromoteObject(HeapObject* object, | 
| } | 
|  | 
|  | 
| +bool MarkCompactCollector::IsSlotInBlackObject(Page* p, Address slot) { | 
| +  // This function does not support large objects right now. | 
| +  if (p->owner() == NULL) return true; | 
| + | 
| +  uint32_t mark_bit_index = p->AddressToMarkbitIndex(slot); | 
| +  unsigned int start_index = mark_bit_index >> Bitmap::kBitsPerCellLog2; | 
| +  MarkBit::CellType index_in_cell = 1U | 
| +                                    << (mark_bit_index & Bitmap::kBitIndexMask); | 
| +  MarkBit::CellType* cells = p->markbits()->cells(); | 
| +  Address cell_base = p->area_start(); | 
| +  unsigned int cell_base_start_index = Bitmap::IndexToCell( | 
| +      Bitmap::CellAlignIndex(p->AddressToMarkbitIndex(cell_base))); | 
| + | 
| +  // First check if the object is in the current cell. | 
| +  MarkBit::CellType slot_mask; | 
| +  if ((cells[start_index] == 0) || | 
| +      (base::bits::CountTrailingZeros32(cells[start_index]) > | 
| +       base::bits::CountTrailingZeros32(cells[start_index] | index_in_cell))) { | 
| +    // If we are already in the first cell, there is no live object. | 
| +    if (start_index == cell_base_start_index) return false; | 
| + | 
| +    // If not, find a cell in a preceding cell slot that has a mark bit set. | 
| +    do { | 
| +      start_index--; | 
| +    } while (start_index > cell_base_start_index && cells[start_index] == 0); | 
| + | 
| +    // The slot must be in a dead object if there are no preceding cells that | 
| +    // have mark bits set. | 
| +    if (cells[start_index] == 0) { | 
| +      return false; | 
| +    } | 
| + | 
| +    // The object is in a preceding cell. Set the mask to find any object. | 
| +    slot_mask = 0xffffffff; | 
| +  } else { | 
| +    // We are interested in object mark bits right before the slot. | 
| +    slot_mask = index_in_cell - 1; | 
| +  } | 
| + | 
| +  MarkBit::CellType current_cell = cells[start_index]; | 
| +  DCHECK(current_cell != 0); | 
| + | 
| +  // Find the last live object in the cell. | 
| +  unsigned int leading_zeros = | 
| +      base::bits::CountLeadingZeros32(current_cell & slot_mask); | 
| +  DCHECK(leading_zeros != 32); | 
| +  unsigned int offset = Bitmap::kBitIndexMask - leading_zeros; | 
| + | 
| +  cell_base += (start_index - cell_base_start_index) * 32 * kPointerSize; | 
| +  Address address = cell_base + offset * kPointerSize; | 
| +  HeapObject* object = HeapObject::FromAddress(address); | 
| +  DCHECK(object->address() < reinterpret_cast<Address>(slot)); | 
| +  if (object->address() <= slot && | 
| +      (object->address() + object->Size()) > slot) { | 
| +    // If the slot is within the last found object in the cell, the slot is | 
| +    // in a live object. | 
| +    return true; | 
| +  } | 
| +  return false; | 
| +} | 
| + | 
| + | 
| +bool MarkCompactCollector::IsSlotInBlackObjectSlow(Page* p, Address slot) { | 
| +  // This function does not support large objects right now. | 
| +  if (p->owner() == NULL) return true; | 
| + | 
| +  for (MarkBitCellIterator it(p); !it.Done(); it.Advance()) { | 
| +    Address cell_base = it.CurrentCellBase(); | 
| +    MarkBit::CellType* cell = it.CurrentCell(); | 
| + | 
| +    MarkBit::CellType current_cell = *cell; | 
| +    if (current_cell == 0) continue; | 
| + | 
| +    int offset = 0; | 
| +    while (current_cell != 0) { | 
| +      int trailing_zeros = base::bits::CountTrailingZeros32(current_cell); | 
| +      current_cell >>= trailing_zeros; | 
| +      offset += trailing_zeros; | 
| +      Address address = cell_base + offset * kPointerSize; | 
| + | 
| +      HeapObject* object = HeapObject::FromAddress(address); | 
| +      int size = object->Size(); | 
| + | 
| +      if (object->address() > slot) return false; | 
| +      if (object->address() <= slot && slot < (object->address() + size)) { | 
| +        return true; | 
| +      } | 
| + | 
| +      offset++; | 
| +      current_cell >>= 1; | 
| +    } | 
| +  } | 
| +  return false; | 
| +} | 
| + | 
| + | 
| +bool MarkCompactCollector::IsSlotInLiveObject(HeapObject** address, | 
| +                                              HeapObject* object) { | 
| +  // If the target object is not black, the source slot must be part | 
| +  // of a non-black (dead) object. | 
| +  if (!Marking::IsBlack(Marking::MarkBitFrom(object))) { | 
| +    return false; | 
| +  } | 
| + | 
| +  // The target object is black but we don't know if the source slot is black. | 
| +  // The source object could have died and the slot could be part of a free | 
| +  // space. Find out based on mark bits if the slot is part of a live object. | 
| +  if (!IsSlotInBlackObject( | 
| +          Page::FromAddress(reinterpret_cast<Address>(address)), | 
| +          reinterpret_cast<Address>(address))) { | 
| +    return false; | 
| +  } | 
| + | 
| +  return true; | 
| +} | 
| + | 
| + | 
| +void MarkCompactCollector::VerifyIsSlotInLiveObject(HeapObject** address, | 
| +                                                    HeapObject* object) { | 
| +  // The target object has to be black. | 
| +  CHECK(Marking::IsBlack(Marking::MarkBitFrom(object))); | 
| + | 
| +  // The target object is black but we don't know if the source slot is black. | 
| +  // The source object could have died and the slot could be part of a free | 
| +  // space. Use the mark bit iterator to find out about liveness of the slot. | 
| +  CHECK(IsSlotInBlackObjectSlow( | 
| +      Page::FromAddress(reinterpret_cast<Address>(address)), | 
| +      reinterpret_cast<Address>(address))); | 
| +} | 
| + | 
| + | 
| void MarkCompactCollector::EvacuateNewSpace() { | 
| // There are soft limits in the allocation code, designed trigger a mark | 
| // sweep collection by failing allocations.  But since we are already in | 
|  |