Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1126)

Unified Diff: src/mark-compact.cc

Issue 155211: Create a new paged heap space for global property cells. The new... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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),
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698