| Index: src/mark-compact.cc
|
| ===================================================================
|
| --- src/mark-compact.cc (revision 2377)
|
| +++ src/mark-compact.cc (working copy)
|
| @@ -56,6 +56,7 @@
|
| int MarkCompactCollector::live_old_pointer_objects_ = 0;
|
| int MarkCompactCollector::live_code_objects_ = 0;
|
| int MarkCompactCollector::live_map_objects_ = 0;
|
| +int MarkCompactCollector::live_cell_objects_ = 0;
|
| int MarkCompactCollector::live_lo_objects_ = 0;
|
| #endif
|
|
|
| @@ -155,6 +156,7 @@
|
| live_old_data_objects_ = 0;
|
| live_code_objects_ = 0;
|
| live_map_objects_ = 0;
|
| + live_cell_objects_ = 0;
|
| live_lo_objects_ = 0;
|
| #endif
|
| }
|
| @@ -708,6 +710,10 @@
|
| ScanOverflowedObjects(&map_it);
|
| if (marking_stack.is_full()) return;
|
|
|
| + HeapObjectIterator cell_it(Heap::cell_space(), &OverflowObjectSize);
|
| + ScanOverflowedObjects(&cell_it);
|
| + if (marking_stack.is_full()) return;
|
| +
|
| LargeObjectIterator lo_it(Heap::lo_space(), &OverflowObjectSize);
|
| ScanOverflowedObjects(&lo_it);
|
| if (marking_stack.is_full()) return;
|
| @@ -808,6 +814,9 @@
|
| } else if (Heap::map_space()->Contains(obj)) {
|
| ASSERT(obj->IsMap());
|
| live_map_objects_++;
|
| + } else if (Heap::cell_space()->Contains(obj)) {
|
| + ASSERT(obj->IsJSGlobalPropertyCell());
|
| + live_cell_objects_++;
|
| } else if (Heap::old_pointer_space()->Contains(obj)) {
|
| live_old_pointer_objects_++;
|
| } else if (Heap::old_data_space()->Contains(obj)) {
|
| @@ -967,27 +976,32 @@
|
|
|
|
|
| // Allocation functions for the paged spaces call the space's MCAllocateRaw.
|
| -inline Object* MCAllocateFromOldPointerSpace(HeapObject* object,
|
| +inline Object* MCAllocateFromOldPointerSpace(HeapObject* ignore,
|
| int object_size) {
|
| return Heap::old_pointer_space()->MCAllocateRaw(object_size);
|
| }
|
|
|
|
|
| -inline Object* MCAllocateFromOldDataSpace(HeapObject* object, int object_size) {
|
| +inline Object* MCAllocateFromOldDataSpace(HeapObject* ignore, int object_size) {
|
| return Heap::old_data_space()->MCAllocateRaw(object_size);
|
| }
|
|
|
|
|
| -inline Object* MCAllocateFromCodeSpace(HeapObject* object, int object_size) {
|
| +inline Object* MCAllocateFromCodeSpace(HeapObject* ignore, int object_size) {
|
| return Heap::code_space()->MCAllocateRaw(object_size);
|
| }
|
|
|
|
|
| -inline Object* MCAllocateFromMapSpace(HeapObject* object, int object_size) {
|
| +inline Object* MCAllocateFromMapSpace(HeapObject* ignore, int object_size) {
|
| return Heap::map_space()->MCAllocateRaw(object_size);
|
| }
|
|
|
|
|
| +inline Object* MCAllocateFromCellSpace(HeapObject* ignore, int object_size) {
|
| + return Heap::cell_space()->MCAllocateRaw(object_size);
|
| +}
|
| +
|
| +
|
| // The forwarding address is encoded at the same offset as the current
|
| // to-space object, but in from space.
|
| inline void EncodeForwardingAddressInNewSpace(HeapObject* old_object,
|
| @@ -1146,7 +1160,7 @@
|
| ByteArray::cast(object)->set_length(ByteArray::LengthFor(size));
|
| } else {
|
| ASSERT(size == kPointerSize);
|
| - object->set_map(Heap::one_word_filler_map());
|
| + object->set_map(Heap::one_pointer_filler_map());
|
| }
|
| ASSERT(object->Size() == size);
|
| }
|
| @@ -1196,8 +1210,8 @@
|
| // loop.
|
| }
|
|
|
| - // If the last region was not live we need to from free_start to the
|
| - // allocation top in the page.
|
| + // If the last region was not live we need to deallocate from
|
| + // free_start to the allocation top in the page.
|
| if (!is_previous_alive) {
|
| int free_size = p->AllocationTop() - free_start;
|
| if (free_size > 0) {
|
| @@ -1241,6 +1255,21 @@
|
| }
|
|
|
|
|
| +void MarkCompactCollector::DeallocateCellBlock(Address start,
|
| + int size_in_bytes) {
|
| + // Free-list elements in cell space are assumed to have a fixed size.
|
| + // We break the free block into chunks and add them to the free list
|
| + // individually.
|
| + int size = Heap::cell_space()->object_size_in_bytes();
|
| + ASSERT(size_in_bytes % size == 0);
|
| + Heap::ClearRSetRange(start, size_in_bytes);
|
| + Address end = start + size_in_bytes;
|
| + for (Address a = start; a < end; a += size) {
|
| + Heap::cell_space()->Free(a);
|
| + }
|
| +}
|
| +
|
| +
|
| void MarkCompactCollector::EncodeForwardingAddresses() {
|
| ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);
|
| // Objects in the active semispace of the young generation may be
|
| @@ -1261,6 +1290,11 @@
|
| LogNonLiveCodeObject>(
|
| Heap::code_space());
|
|
|
| + EncodeForwardingAddressesInPagedSpace<MCAllocateFromCellSpace,
|
| + IgnoreNonLiveObject>(
|
| + Heap::cell_space());
|
| +
|
| +
|
| // Compute new space next to last after the old and code spaces have been
|
| // compacted. Objects in new space can be promoted to old or code space.
|
| EncodeForwardingAddressesInNewSpace();
|
| @@ -1279,6 +1313,7 @@
|
| Heap::old_data_space()->MCWriteRelocationInfoToPage();
|
| Heap::code_space()->MCWriteRelocationInfoToPage();
|
| Heap::map_space()->MCWriteRelocationInfoToPage();
|
| + Heap::cell_space()->MCWriteRelocationInfoToPage();
|
| }
|
|
|
|
|
| @@ -1293,6 +1328,7 @@
|
| SweepSpace(Heap::old_pointer_space(), &DeallocateOldPointerBlock);
|
| SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock);
|
| SweepSpace(Heap::code_space(), &DeallocateCodeBlock);
|
| + SweepSpace(Heap::cell_space(), &DeallocateCellBlock);
|
| SweepSpace(Heap::new_space());
|
| SweepSpace(Heap::map_space(), &DeallocateMapBlock);
|
| }
|
| @@ -1371,15 +1407,16 @@
|
| ASSERT(!Heap::InFromSpace(obj));
|
|
|
| if (Heap::new_space()->Contains(obj)) {
|
| - Address f_addr = Heap::new_space()->FromSpaceLow() +
|
| - Heap::new_space()->ToSpaceOffsetForAddress(old_addr);
|
| - new_addr = Memory::Address_at(f_addr);
|
| + Address forwarding_pointer_addr =
|
| + Heap::new_space()->FromSpaceLow() +
|
| + Heap::new_space()->ToSpaceOffsetForAddress(old_addr);
|
| + new_addr = Memory::Address_at(forwarding_pointer_addr);
|
|
|
| #ifdef DEBUG
|
| ASSERT(Heap::old_pointer_space()->Contains(new_addr) ||
|
| Heap::old_data_space()->Contains(new_addr) ||
|
| - Heap::code_space()->Contains(new_addr) ||
|
| - Heap::new_space()->FromSpaceContains(new_addr));
|
| + Heap::new_space()->FromSpaceContains(new_addr) ||
|
| + Heap::lo_space()->Contains(HeapObject::FromAddress(new_addr)));
|
|
|
| if (Heap::new_space()->FromSpaceContains(new_addr)) {
|
| ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <=
|
| @@ -1392,32 +1429,19 @@
|
| return;
|
|
|
| } else {
|
| - ASSERT(Heap::old_pointer_space()->Contains(obj) ||
|
| - Heap::old_data_space()->Contains(obj) ||
|
| - Heap::code_space()->Contains(obj) ||
|
| - Heap::map_space()->Contains(obj));
|
| -
|
| - new_addr = MarkCompactCollector::GetForwardingAddressInOldSpace(obj);
|
| - ASSERT(Heap::old_pointer_space()->Contains(new_addr) ||
|
| - Heap::old_data_space()->Contains(new_addr) ||
|
| - Heap::code_space()->Contains(new_addr) ||
|
| - Heap::map_space()->Contains(new_addr));
|
| -
|
| #ifdef DEBUG
|
| - if (Heap::old_pointer_space()->Contains(obj)) {
|
| - ASSERT(Heap::old_pointer_space()->MCSpaceOffsetForAddress(new_addr) <=
|
| - Heap::old_pointer_space()->MCSpaceOffsetForAddress(old_addr));
|
| - } else if (Heap::old_data_space()->Contains(obj)) {
|
| - ASSERT(Heap::old_data_space()->MCSpaceOffsetForAddress(new_addr) <=
|
| - Heap::old_data_space()->MCSpaceOffsetForAddress(old_addr));
|
| - } else if (Heap::code_space()->Contains(obj)) {
|
| - ASSERT(Heap::code_space()->MCSpaceOffsetForAddress(new_addr) <=
|
| - Heap::code_space()->MCSpaceOffsetForAddress(old_addr));
|
| - } else {
|
| - ASSERT(Heap::map_space()->MCSpaceOffsetForAddress(new_addr) <=
|
| - Heap::map_space()->MCSpaceOffsetForAddress(old_addr));
|
| + PagedSpaces spaces;
|
| + PagedSpace* original_space = spaces.next();
|
| + while (original_space != NULL) {
|
| + if (original_space->Contains(obj)) break;
|
| + original_space = spaces.next();
|
| }
|
| + ASSERT(original_space != NULL);
|
| #endif
|
| + new_addr = MarkCompactCollector::GetForwardingAddressInOldSpace(obj);
|
| + ASSERT(original_space->Contains(new_addr));
|
| + ASSERT(original_space->MCSpaceOffsetForAddress(new_addr) <=
|
| + original_space->MCSpaceOffsetForAddress(old_addr));
|
| }
|
|
|
| *p = HeapObject::FromAddress(new_addr);
|
| @@ -1449,6 +1473,8 @@
|
| &UpdatePointersInOldObject);
|
| int live_codes = IterateLiveObjects(Heap::code_space(),
|
| &UpdatePointersInOldObject);
|
| + int live_cells = IterateLiveObjects(Heap::cell_space(),
|
| + &UpdatePointersInOldObject);
|
| int live_news = IterateLiveObjects(Heap::new_space(),
|
| &UpdatePointersInNewObject);
|
|
|
| @@ -1460,15 +1486,14 @@
|
| USE(live_pointer_olds);
|
| USE(live_data_olds);
|
| USE(live_codes);
|
| + USE(live_cells);
|
| USE(live_news);
|
| -
|
| -#ifdef DEBUG
|
| ASSERT(live_maps == live_map_objects_);
|
| ASSERT(live_data_olds == live_old_data_objects_);
|
| ASSERT(live_pointer_olds == live_old_pointer_objects_);
|
| ASSERT(live_codes == live_code_objects_);
|
| + ASSERT(live_cells == live_cell_objects_);
|
| ASSERT(live_news == live_young_objects_);
|
| -#endif
|
| }
|
|
|
|
|
| @@ -1589,30 +1614,31 @@
|
| int live_data_olds = IterateLiveObjects(Heap::old_data_space(),
|
| &RelocateOldDataObject);
|
| int live_codes = IterateLiveObjects(Heap::code_space(), &RelocateCodeObject);
|
| + int live_cells = IterateLiveObjects(Heap::cell_space(), &RelocateCellObject);
|
| int live_news = IterateLiveObjects(Heap::new_space(), &RelocateNewObject);
|
|
|
| USE(live_maps);
|
| USE(live_data_olds);
|
| USE(live_pointer_olds);
|
| USE(live_codes);
|
| + USE(live_cells);
|
| USE(live_news);
|
| -#ifdef DEBUG
|
| ASSERT(live_maps == live_map_objects_);
|
| ASSERT(live_data_olds == live_old_data_objects_);
|
| ASSERT(live_pointer_olds == live_old_pointer_objects_);
|
| ASSERT(live_codes == live_code_objects_);
|
| + ASSERT(live_cells == live_cell_objects_);
|
| ASSERT(live_news == live_young_objects_);
|
| -#endif
|
|
|
| // Notify code object in LO to convert IC target to address
|
| // This must happen after lo_space_->Compact
|
| LargeObjectIterator it(Heap::lo_space());
|
| while (it.has_next()) { ConvertCodeICTargetToAddress(it.next()); }
|
|
|
| - // Flips from and to spaces
|
| + // Flip from and to spaces
|
| Heap::new_space()->Flip();
|
|
|
| - // Sets age_mark to bottom in to space
|
| + // Set age_mark to bottom in to space
|
| Address mark = Heap::new_space()->bottom();
|
| Heap::new_space()->set_age_mark(mark);
|
|
|
| @@ -1636,7 +1662,7 @@
|
|
|
|
|
| int MarkCompactCollector::RelocateMapObject(HeapObject* obj) {
|
| - // decode map pointer (forwarded address)
|
| + // Recover map pointer.
|
| MapWord encoding = obj->map_word();
|
| Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
|
| ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));
|
| @@ -1644,10 +1670,10 @@
|
| // Get forwarding address before resetting map pointer
|
| Address new_addr = GetForwardingAddressInOldSpace(obj);
|
|
|
| - // recover map pointer
|
| + // Reset map pointer. The meta map object may not be copied yet so
|
| + // Map::cast does not yet work.
|
| obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr)));
|
|
|
| - // The meta map object may not be copied yet.
|
| Address old_addr = obj->address();
|
|
|
| if (new_addr != old_addr) {
|
| @@ -1664,23 +1690,23 @@
|
| }
|
|
|
|
|
| -static inline int RelocateOldObject(HeapObject* obj,
|
| - OldSpace* space,
|
| - Address new_addr,
|
| - Address map_addr) {
|
| - // recover map pointer
|
| - obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr)));
|
| +static inline int RestoreMap(HeapObject* obj,
|
| + PagedSpace* space,
|
| + Address new_addr,
|
| + Address map_addr) {
|
| + // This must be a non-map object, and the function relies on the
|
| + // assumption that the Map space is compacted before the other paged
|
| + // spaces (see RelocateObjects).
|
|
|
| - // This is a non-map object, it relies on the assumption that the Map space
|
| - // is compacted before the Old space (see RelocateObjects).
|
| + // Reset map pointer.
|
| + obj->set_map(Map::cast(HeapObject::FromAddress(map_addr)));
|
| +
|
| int obj_size = obj->Size();
|
| ASSERT_OBJECT_SIZE(obj_size);
|
|
|
| ASSERT(space->MCSpaceOffsetForAddress(new_addr) <=
|
| space->MCSpaceOffsetForAddress(obj->address()));
|
|
|
| - space->MCAdjustRelocationEnd(new_addr, obj_size);
|
| -
|
| #ifdef DEBUG
|
| if (FLAG_gc_verbose) {
|
| PrintF("relocate %p -> %p\n", obj->address(), new_addr);
|
| @@ -1692,21 +1718,22 @@
|
|
|
|
|
| int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj,
|
| - OldSpace* space) {
|
| - // decode map pointer (forwarded address)
|
| + PagedSpace* space) {
|
| + // Recover map pointer.
|
| MapWord encoding = obj->map_word();
|
| Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
|
| ASSERT(Heap::map_space()->Contains(map_addr));
|
|
|
| - // Get forwarding address before resetting map pointer
|
| + // Get forwarding address before resetting map pointer.
|
| Address new_addr = GetForwardingAddressInOldSpace(obj);
|
|
|
| - int obj_size = RelocateOldObject(obj, space, new_addr, map_addr);
|
| + // Reset the map pointer.
|
| + int obj_size = RestoreMap(obj, space, new_addr, map_addr);
|
|
|
| Address old_addr = obj->address();
|
|
|
| if (new_addr != old_addr) {
|
| - memmove(new_addr, old_addr, obj_size); // copy contents
|
| + memmove(new_addr, old_addr, obj_size); // Copy contents
|
| }
|
|
|
| ASSERT(!HeapObject::FromAddress(new_addr)->IsCode());
|
| @@ -1725,8 +1752,13 @@
|
| }
|
|
|
|
|
| +int MarkCompactCollector::RelocateCellObject(HeapObject* obj) {
|
| + return RelocateOldNonCodeObject(obj, Heap::cell_space());
|
| +}
|
| +
|
| +
|
| int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {
|
| - // decode map pointer (forwarded address)
|
| + // Recover map pointer.
|
| MapWord encoding = obj->map_word();
|
| Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
|
| ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));
|
| @@ -1734,23 +1766,23 @@
|
| // Get forwarding address before resetting map pointer
|
| Address new_addr = GetForwardingAddressInOldSpace(obj);
|
|
|
| - int obj_size = RelocateOldObject(obj, Heap::code_space(), new_addr, map_addr);
|
| + // Reset the map pointer.
|
| + int obj_size = RestoreMap(obj, Heap::code_space(), new_addr, map_addr);
|
|
|
| - // convert inline cache target to address using old address
|
| + // Convert inline cache target to address using old address.
|
| if (obj->IsCode()) {
|
| - // convert target to address first related to old_address
|
| Code::cast(obj)->ConvertICTargetsFromObjectToAddress();
|
| }
|
|
|
| Address old_addr = obj->address();
|
|
|
| if (new_addr != old_addr) {
|
| - memmove(new_addr, old_addr, obj_size); // copy contents
|
| + memmove(new_addr, old_addr, obj_size); // Copy contents.
|
| }
|
|
|
| HeapObject* copied_to = HeapObject::FromAddress(new_addr);
|
| if (copied_to->IsCode()) {
|
| - // may also update inline cache target.
|
| + // May also update inline cache target.
|
| Code::cast(copied_to)->Relocate(new_addr - old_addr);
|
| // Notify the logger that compiled code has moved.
|
| LOG(CodeMoveEvent(old_addr, new_addr));
|
| @@ -1770,15 +1802,15 @@
|
| Address new_addr =
|
| Memory::Address_at(Heap::new_space()->FromSpaceLow() + offset);
|
|
|
| +#ifdef DEBUG
|
| if (Heap::new_space()->FromSpaceContains(new_addr)) {
|
| ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <=
|
| Heap::new_space()->ToSpaceOffsetForAddress(old_addr));
|
| } else {
|
| - OldSpace* target_space = Heap::TargetSpace(obj);
|
| - ASSERT(target_space == Heap::old_pointer_space() ||
|
| - target_space == Heap::old_data_space());
|
| - target_space->MCAdjustRelocationEnd(new_addr, obj_size);
|
| + ASSERT(Heap::TargetSpace(obj) == Heap::old_pointer_space() ||
|
| + Heap::TargetSpace(obj) == Heap::old_data_space());
|
| }
|
| +#endif
|
|
|
| // New and old addresses cannot overlap.
|
| memcpy(reinterpret_cast<void*>(new_addr),
|
|
|