| Index: src/heap-inl.h
 | 
| diff --git a/src/heap-inl.h b/src/heap-inl.h
 | 
| index 82e1a9125d668e4f07366981fe8357691de5585a..80157d019d758f5739a03eeb5bd3e6db21b40c8a 100644
 | 
| --- a/src/heap-inl.h
 | 
| +++ b/src/heap-inl.h
 | 
| @@ -184,7 +184,7 @@ void Heap::RecordWrite(Address address, int offset) {
 | 
|    if (new_space_.Contains(address)) return;
 | 
|    ASSERT(!new_space_.FromSpaceContains(address));
 | 
|    SLOW_ASSERT(Contains(address + offset));
 | 
| -  Page::SetRSet(address, offset);
 | 
| +  Page::FromAddress(address)->MarkRegionDirty(address + offset);
 | 
|  }
 | 
|  
 | 
|  
 | 
| @@ -195,7 +195,7 @@ void Heap::RecordWrites(Address address, int start, int len) {
 | 
|         offset < start + len * kPointerSize;
 | 
|         offset += kPointerSize) {
 | 
|      SLOW_ASSERT(Contains(address + offset));
 | 
| -    Page::SetRSet(address, offset);
 | 
| +    Page::FromAddress(address)->MarkRegionDirty(address + offset);
 | 
|    }
 | 
|  }
 | 
|  
 | 
| @@ -234,13 +234,40 @@ AllocationSpace Heap::TargetSpaceId(InstanceType type) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void Heap::CopyBlock(Object** dst, Object** src, int byte_size) {
 | 
| +void Heap::CopyBlock(Address dst, Address src, int byte_size) {
 | 
|    ASSERT(IsAligned(byte_size, kPointerSize));
 | 
| -  CopyWords(dst, src, byte_size / kPointerSize);
 | 
| +  CopyWords(reinterpret_cast<Object**>(dst),
 | 
| +            reinterpret_cast<Object**>(src),
 | 
| +            byte_size / kPointerSize);
 | 
|  }
 | 
|  
 | 
|  
 | 
| -void Heap::MoveBlock(Object** dst, Object** src, int byte_size) {
 | 
| +void Heap::CopyBlockToOldSpaceAndUpdateRegionMarks(Address dst,
 | 
| +                                                   Address src,
 | 
| +                                                   int byte_size) {
 | 
| +  ASSERT(IsAligned(byte_size, kPointerSize));
 | 
| +
 | 
| +  Page* page = Page::FromAddress(dst);
 | 
| +  uint32_t marks = page->GetRegionMarks();
 | 
| +
 | 
| +  for (int remaining = byte_size / kPointerSize;
 | 
| +       remaining > 0;
 | 
| +       remaining--) {
 | 
| +    Memory::Object_at(dst) = Memory::Object_at(src);
 | 
| +
 | 
| +    if (Heap::InNewSpace(Memory::Object_at(dst))) {
 | 
| +      marks |= page->GetRegionMaskForAddress(dst);
 | 
| +    }
 | 
| +
 | 
| +    dst += kPointerSize;
 | 
| +    src += kPointerSize;
 | 
| +  }
 | 
| +
 | 
| +  page->SetRegionMarks(marks);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +void Heap::MoveBlock(Address dst, Address src, int byte_size) {
 | 
|    ASSERT(IsAligned(byte_size, kPointerSize));
 | 
|  
 | 
|    int size_in_words = byte_size / kPointerSize;
 | 
| @@ -250,10 +277,12 @@ void Heap::MoveBlock(Object** dst, Object** src, int byte_size) {
 | 
|             ((OffsetFrom(reinterpret_cast<Address>(src)) -
 | 
|               OffsetFrom(reinterpret_cast<Address>(dst))) >= kPointerSize));
 | 
|  
 | 
| -    Object** end = src + size_in_words;
 | 
| +    Object** src_slot = reinterpret_cast<Object**>(src);
 | 
| +    Object** dst_slot = reinterpret_cast<Object**>(dst);
 | 
| +    Object** end_slot = src_slot + size_in_words;
 | 
|  
 | 
| -    while (src != end) {
 | 
| -      *dst++ = *src++;
 | 
| +    while (src_slot != end_slot) {
 | 
| +      *dst_slot++ = *src_slot++;
 | 
|      }
 | 
|    } else {
 | 
|      memmove(dst, src, byte_size);
 | 
| @@ -261,6 +290,17 @@ void Heap::MoveBlock(Object** dst, Object** src, int byte_size) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void Heap::MoveBlockToOldSpaceAndUpdateRegionMarks(Address dst,
 | 
| +                                                   Address src,
 | 
| +                                                   int byte_size) {
 | 
| +  ASSERT(IsAligned(byte_size, kPointerSize));
 | 
| +  ASSERT((dst >= (src + byte_size)) ||
 | 
| +         ((OffsetFrom(src) - OffsetFrom(dst)) >= kPointerSize));
 | 
| +
 | 
| +  CopyBlockToOldSpaceAndUpdateRegionMarks(dst, src, byte_size);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  void Heap::ScavengeObject(HeapObject** p, HeapObject* object) {
 | 
|    ASSERT(InFromSpace(object));
 | 
|  
 | 
| 
 |