OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 MarkCompactCollector::CollectorState MarkCompactCollector::state_ = IDLE; | 49 MarkCompactCollector::CollectorState MarkCompactCollector::state_ = IDLE; |
50 | 50 |
51 // Counters used for debugging the marking phase of mark-compact or mark-sweep | 51 // Counters used for debugging the marking phase of mark-compact or mark-sweep |
52 // collection. | 52 // collection. |
53 int MarkCompactCollector::live_bytes_ = 0; | 53 int MarkCompactCollector::live_bytes_ = 0; |
54 int MarkCompactCollector::live_young_objects_ = 0; | 54 int MarkCompactCollector::live_young_objects_ = 0; |
55 int MarkCompactCollector::live_old_data_objects_ = 0; | 55 int MarkCompactCollector::live_old_data_objects_ = 0; |
56 int MarkCompactCollector::live_old_pointer_objects_ = 0; | 56 int MarkCompactCollector::live_old_pointer_objects_ = 0; |
57 int MarkCompactCollector::live_code_objects_ = 0; | 57 int MarkCompactCollector::live_code_objects_ = 0; |
58 int MarkCompactCollector::live_map_objects_ = 0; | 58 int MarkCompactCollector::live_map_objects_ = 0; |
| 59 int MarkCompactCollector::live_cell_objects_ = 0; |
59 int MarkCompactCollector::live_lo_objects_ = 0; | 60 int MarkCompactCollector::live_lo_objects_ = 0; |
60 #endif | 61 #endif |
61 | 62 |
62 void MarkCompactCollector::CollectGarbage() { | 63 void MarkCompactCollector::CollectGarbage() { |
63 // Make sure that Prepare() has been called. The individual steps below will | 64 // Make sure that Prepare() has been called. The individual steps below will |
64 // update the state as they proceed. | 65 // update the state as they proceed. |
65 ASSERT(state_ == PREPARE_GC); | 66 ASSERT(state_ == PREPARE_GC); |
66 | 67 |
67 // Prepare has selected whether to compact the old generation or not. | 68 // Prepare has selected whether to compact the old generation or not. |
68 // Tell the tracer. | 69 // Tell the tracer. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 space->PrepareForMarkCompact(compacting_collection_); | 149 space->PrepareForMarkCompact(compacting_collection_); |
149 } | 150 } |
150 | 151 |
151 #ifdef DEBUG | 152 #ifdef DEBUG |
152 live_bytes_ = 0; | 153 live_bytes_ = 0; |
153 live_young_objects_ = 0; | 154 live_young_objects_ = 0; |
154 live_old_pointer_objects_ = 0; | 155 live_old_pointer_objects_ = 0; |
155 live_old_data_objects_ = 0; | 156 live_old_data_objects_ = 0; |
156 live_code_objects_ = 0; | 157 live_code_objects_ = 0; |
157 live_map_objects_ = 0; | 158 live_map_objects_ = 0; |
| 159 live_cell_objects_ = 0; |
158 live_lo_objects_ = 0; | 160 live_lo_objects_ = 0; |
159 #endif | 161 #endif |
160 } | 162 } |
161 | 163 |
162 | 164 |
163 void MarkCompactCollector::Finish() { | 165 void MarkCompactCollector::Finish() { |
164 #ifdef DEBUG | 166 #ifdef DEBUG |
165 ASSERT(state_ == SWEEP_SPACES || state_ == REBUILD_RSETS); | 167 ASSERT(state_ == SWEEP_SPACES || state_ == REBUILD_RSETS); |
166 state_ = IDLE; | 168 state_ = IDLE; |
167 #endif | 169 #endif |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 if (marking_stack.is_full()) return; | 703 if (marking_stack.is_full()) return; |
702 | 704 |
703 HeapObjectIterator code_it(Heap::code_space(), &OverflowObjectSize); | 705 HeapObjectIterator code_it(Heap::code_space(), &OverflowObjectSize); |
704 ScanOverflowedObjects(&code_it); | 706 ScanOverflowedObjects(&code_it); |
705 if (marking_stack.is_full()) return; | 707 if (marking_stack.is_full()) return; |
706 | 708 |
707 HeapObjectIterator map_it(Heap::map_space(), &OverflowObjectSize); | 709 HeapObjectIterator map_it(Heap::map_space(), &OverflowObjectSize); |
708 ScanOverflowedObjects(&map_it); | 710 ScanOverflowedObjects(&map_it); |
709 if (marking_stack.is_full()) return; | 711 if (marking_stack.is_full()) return; |
710 | 712 |
| 713 HeapObjectIterator cell_it(Heap::cell_space(), &OverflowObjectSize); |
| 714 ScanOverflowedObjects(&cell_it); |
| 715 if (marking_stack.is_full()) return; |
| 716 |
711 LargeObjectIterator lo_it(Heap::lo_space(), &OverflowObjectSize); | 717 LargeObjectIterator lo_it(Heap::lo_space(), &OverflowObjectSize); |
712 ScanOverflowedObjects(&lo_it); | 718 ScanOverflowedObjects(&lo_it); |
713 if (marking_stack.is_full()) return; | 719 if (marking_stack.is_full()) return; |
714 | 720 |
715 marking_stack.clear_overflowed(); | 721 marking_stack.clear_overflowed(); |
716 } | 722 } |
717 | 723 |
718 | 724 |
719 // Mark all objects reachable (transitively) from objects on the marking | 725 // Mark all objects reachable (transitively) from objects on the marking |
720 // stack. Before: the marking stack contains zero or more heap object | 726 // stack. Before: the marking stack contains zero or more heap object |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 | 807 |
802 | 808 |
803 #ifdef DEBUG | 809 #ifdef DEBUG |
804 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) { | 810 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) { |
805 live_bytes_ += obj->Size(); | 811 live_bytes_ += obj->Size(); |
806 if (Heap::new_space()->Contains(obj)) { | 812 if (Heap::new_space()->Contains(obj)) { |
807 live_young_objects_++; | 813 live_young_objects_++; |
808 } else if (Heap::map_space()->Contains(obj)) { | 814 } else if (Heap::map_space()->Contains(obj)) { |
809 ASSERT(obj->IsMap()); | 815 ASSERT(obj->IsMap()); |
810 live_map_objects_++; | 816 live_map_objects_++; |
| 817 } else if (Heap::cell_space()->Contains(obj)) { |
| 818 ASSERT(obj->IsJSGlobalPropertyCell()); |
| 819 live_cell_objects_++; |
811 } else if (Heap::old_pointer_space()->Contains(obj)) { | 820 } else if (Heap::old_pointer_space()->Contains(obj)) { |
812 live_old_pointer_objects_++; | 821 live_old_pointer_objects_++; |
813 } else if (Heap::old_data_space()->Contains(obj)) { | 822 } else if (Heap::old_data_space()->Contains(obj)) { |
814 live_old_data_objects_++; | 823 live_old_data_objects_++; |
815 } else if (Heap::code_space()->Contains(obj)) { | 824 } else if (Heap::code_space()->Contains(obj)) { |
816 live_code_objects_++; | 825 live_code_objects_++; |
817 } else if (Heap::lo_space()->Contains(obj)) { | 826 } else if (Heap::lo_space()->Contains(obj)) { |
818 live_lo_objects_++; | 827 live_lo_objects_++; |
819 } else { | 828 } else { |
820 UNREACHABLE(); | 829 UNREACHABLE(); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 forwarded = target_space->MCAllocateRaw(object_size); | 969 forwarded = target_space->MCAllocateRaw(object_size); |
961 } | 970 } |
962 if (forwarded->IsFailure()) { | 971 if (forwarded->IsFailure()) { |
963 forwarded = Heap::new_space()->MCAllocateRaw(object_size); | 972 forwarded = Heap::new_space()->MCAllocateRaw(object_size); |
964 } | 973 } |
965 return forwarded; | 974 return forwarded; |
966 } | 975 } |
967 | 976 |
968 | 977 |
969 // Allocation functions for the paged spaces call the space's MCAllocateRaw. | 978 // Allocation functions for the paged spaces call the space's MCAllocateRaw. |
970 inline Object* MCAllocateFromOldPointerSpace(HeapObject* object, | 979 inline Object* MCAllocateFromOldPointerSpace(HeapObject* ignore, |
971 int object_size) { | 980 int object_size) { |
972 return Heap::old_pointer_space()->MCAllocateRaw(object_size); | 981 return Heap::old_pointer_space()->MCAllocateRaw(object_size); |
973 } | 982 } |
974 | 983 |
975 | 984 |
976 inline Object* MCAllocateFromOldDataSpace(HeapObject* object, int object_size) { | 985 inline Object* MCAllocateFromOldDataSpace(HeapObject* ignore, int object_size) { |
977 return Heap::old_data_space()->MCAllocateRaw(object_size); | 986 return Heap::old_data_space()->MCAllocateRaw(object_size); |
978 } | 987 } |
979 | 988 |
980 | 989 |
981 inline Object* MCAllocateFromCodeSpace(HeapObject* object, int object_size) { | 990 inline Object* MCAllocateFromCodeSpace(HeapObject* ignore, int object_size) { |
982 return Heap::code_space()->MCAllocateRaw(object_size); | 991 return Heap::code_space()->MCAllocateRaw(object_size); |
983 } | 992 } |
984 | 993 |
985 | 994 |
986 inline Object* MCAllocateFromMapSpace(HeapObject* object, int object_size) { | 995 inline Object* MCAllocateFromMapSpace(HeapObject* ignore, int object_size) { |
987 return Heap::map_space()->MCAllocateRaw(object_size); | 996 return Heap::map_space()->MCAllocateRaw(object_size); |
988 } | 997 } |
989 | 998 |
990 | 999 |
| 1000 inline Object* MCAllocateFromCellSpace(HeapObject* ignore, int object_size) { |
| 1001 return Heap::cell_space()->MCAllocateRaw(object_size); |
| 1002 } |
| 1003 |
| 1004 |
991 // The forwarding address is encoded at the same offset as the current | 1005 // The forwarding address is encoded at the same offset as the current |
992 // to-space object, but in from space. | 1006 // to-space object, but in from space. |
993 inline void EncodeForwardingAddressInNewSpace(HeapObject* old_object, | 1007 inline void EncodeForwardingAddressInNewSpace(HeapObject* old_object, |
994 int object_size, | 1008 int object_size, |
995 Object* new_object, | 1009 Object* new_object, |
996 int* ignored) { | 1010 int* ignored) { |
997 int offset = | 1011 int offset = |
998 Heap::new_space()->ToSpaceOffsetForAddress(old_object->address()); | 1012 Heap::new_space()->ToSpaceOffsetForAddress(old_object->address()); |
999 Memory::Address_at(Heap::new_space()->FromSpaceLow() + offset) = | 1013 Memory::Address_at(Heap::new_space()->FromSpaceLow() + offset) = |
1000 HeapObject::cast(new_object)->address(); | 1014 HeapObject::cast(new_object)->address(); |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 MarkCompactCollector::tracer()->decrement_marked_count(); | 1153 MarkCompactCollector::tracer()->decrement_marked_count(); |
1140 } else { | 1154 } else { |
1141 // We give non-live objects a map that will correctly give their size, | 1155 // We give non-live objects a map that will correctly give their size, |
1142 // since their existing map might not be live after the collection. | 1156 // since their existing map might not be live after the collection. |
1143 int size = object->Size(); | 1157 int size = object->Size(); |
1144 if (size >= ByteArray::kHeaderSize) { | 1158 if (size >= ByteArray::kHeaderSize) { |
1145 object->set_map(Heap::byte_array_map()); | 1159 object->set_map(Heap::byte_array_map()); |
1146 ByteArray::cast(object)->set_length(ByteArray::LengthFor(size)); | 1160 ByteArray::cast(object)->set_length(ByteArray::LengthFor(size)); |
1147 } else { | 1161 } else { |
1148 ASSERT(size == kPointerSize); | 1162 ASSERT(size == kPointerSize); |
1149 object->set_map(Heap::one_word_filler_map()); | 1163 object->set_map(Heap::one_pointer_filler_map()); |
1150 } | 1164 } |
1151 ASSERT(object->Size() == size); | 1165 ASSERT(object->Size() == size); |
1152 } | 1166 } |
1153 // The object is now unmarked for the call to Size() at the top of the | 1167 // The object is now unmarked for the call to Size() at the top of the |
1154 // loop. | 1168 // loop. |
1155 } | 1169 } |
1156 } | 1170 } |
1157 | 1171 |
1158 | 1172 |
1159 static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) { | 1173 static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) { |
(...skipping 29 matching lines...) Expand all Loading... |
1189 } | 1203 } |
1190 if (is_previous_alive) { // Transition from live to free. | 1204 if (is_previous_alive) { // Transition from live to free. |
1191 free_start = current; | 1205 free_start = current; |
1192 is_previous_alive = false; | 1206 is_previous_alive = false; |
1193 } | 1207 } |
1194 } | 1208 } |
1195 // The object is now unmarked for the call to Size() at the top of the | 1209 // The object is now unmarked for the call to Size() at the top of the |
1196 // loop. | 1210 // loop. |
1197 } | 1211 } |
1198 | 1212 |
1199 // If the last region was not live we need to from free_start to the | 1213 // If the last region was not live we need to deallocate from |
1200 // allocation top in the page. | 1214 // free_start to the allocation top in the page. |
1201 if (!is_previous_alive) { | 1215 if (!is_previous_alive) { |
1202 int free_size = p->AllocationTop() - free_start; | 1216 int free_size = p->AllocationTop() - free_start; |
1203 if (free_size > 0) { | 1217 if (free_size > 0) { |
1204 dealloc(free_start, free_size); | 1218 dealloc(free_start, free_size); |
1205 } | 1219 } |
1206 } | 1220 } |
1207 } | 1221 } |
1208 } | 1222 } |
1209 | 1223 |
1210 | 1224 |
(...skipping 23 matching lines...) Expand all Loading... |
1234 // chunks and free them separately. | 1248 // chunks and free them separately. |
1235 ASSERT(size_in_bytes % Map::kSize == 0); | 1249 ASSERT(size_in_bytes % Map::kSize == 0); |
1236 Heap::ClearRSetRange(start, size_in_bytes); | 1250 Heap::ClearRSetRange(start, size_in_bytes); |
1237 Address end = start + size_in_bytes; | 1251 Address end = start + size_in_bytes; |
1238 for (Address a = start; a < end; a += Map::kSize) { | 1252 for (Address a = start; a < end; a += Map::kSize) { |
1239 Heap::map_space()->Free(a); | 1253 Heap::map_space()->Free(a); |
1240 } | 1254 } |
1241 } | 1255 } |
1242 | 1256 |
1243 | 1257 |
| 1258 void MarkCompactCollector::DeallocateCellBlock(Address start, |
| 1259 int size_in_bytes) { |
| 1260 // Free-list elements in cell space are assumed to have a fixed size. |
| 1261 // We break the free block into chunks and add them to the free list |
| 1262 // individually. |
| 1263 int size = Heap::cell_space()->object_size_in_bytes(); |
| 1264 ASSERT(size_in_bytes % size == 0); |
| 1265 Heap::ClearRSetRange(start, size_in_bytes); |
| 1266 Address end = start + size_in_bytes; |
| 1267 for (Address a = start; a < end; a += size) { |
| 1268 Heap::cell_space()->Free(a); |
| 1269 } |
| 1270 } |
| 1271 |
| 1272 |
1244 void MarkCompactCollector::EncodeForwardingAddresses() { | 1273 void MarkCompactCollector::EncodeForwardingAddresses() { |
1245 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); | 1274 ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES); |
1246 // Objects in the active semispace of the young generation may be | 1275 // Objects in the active semispace of the young generation may be |
1247 // relocated to the inactive semispace (if not promoted). Set the | 1276 // relocated to the inactive semispace (if not promoted). Set the |
1248 // relocation info to the beginning of the inactive semispace. | 1277 // relocation info to the beginning of the inactive semispace. |
1249 Heap::new_space()->MCResetRelocationInfo(); | 1278 Heap::new_space()->MCResetRelocationInfo(); |
1250 | 1279 |
1251 // Compute the forwarding pointers in each space. | 1280 // Compute the forwarding pointers in each space. |
1252 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace, | 1281 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldPointerSpace, |
1253 IgnoreNonLiveObject>( | 1282 IgnoreNonLiveObject>( |
1254 Heap::old_pointer_space()); | 1283 Heap::old_pointer_space()); |
1255 | 1284 |
1256 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldDataSpace, | 1285 EncodeForwardingAddressesInPagedSpace<MCAllocateFromOldDataSpace, |
1257 IgnoreNonLiveObject>( | 1286 IgnoreNonLiveObject>( |
1258 Heap::old_data_space()); | 1287 Heap::old_data_space()); |
1259 | 1288 |
1260 EncodeForwardingAddressesInPagedSpace<MCAllocateFromCodeSpace, | 1289 EncodeForwardingAddressesInPagedSpace<MCAllocateFromCodeSpace, |
1261 LogNonLiveCodeObject>( | 1290 LogNonLiveCodeObject>( |
1262 Heap::code_space()); | 1291 Heap::code_space()); |
1263 | 1292 |
| 1293 EncodeForwardingAddressesInPagedSpace<MCAllocateFromCellSpace, |
| 1294 IgnoreNonLiveObject>( |
| 1295 Heap::cell_space()); |
| 1296 |
| 1297 |
1264 // Compute new space next to last after the old and code spaces have been | 1298 // Compute new space next to last after the old and code spaces have been |
1265 // compacted. Objects in new space can be promoted to old or code space. | 1299 // compacted. Objects in new space can be promoted to old or code space. |
1266 EncodeForwardingAddressesInNewSpace(); | 1300 EncodeForwardingAddressesInNewSpace(); |
1267 | 1301 |
1268 // Compute map space last because computing forwarding addresses | 1302 // Compute map space last because computing forwarding addresses |
1269 // overwrites non-live objects. Objects in the other spaces rely on | 1303 // overwrites non-live objects. Objects in the other spaces rely on |
1270 // non-live map pointers to get the sizes of non-live objects. | 1304 // non-live map pointers to get the sizes of non-live objects. |
1271 EncodeForwardingAddressesInPagedSpace<MCAllocateFromMapSpace, | 1305 EncodeForwardingAddressesInPagedSpace<MCAllocateFromMapSpace, |
1272 IgnoreNonLiveObject>( | 1306 IgnoreNonLiveObject>( |
1273 Heap::map_space()); | 1307 Heap::map_space()); |
1274 | 1308 |
1275 // Write relocation info to the top page, so we can use it later. This is | 1309 // Write relocation info to the top page, so we can use it later. This is |
1276 // done after promoting objects from the new space so we get the correct | 1310 // done after promoting objects from the new space so we get the correct |
1277 // allocation top. | 1311 // allocation top. |
1278 Heap::old_pointer_space()->MCWriteRelocationInfoToPage(); | 1312 Heap::old_pointer_space()->MCWriteRelocationInfoToPage(); |
1279 Heap::old_data_space()->MCWriteRelocationInfoToPage(); | 1313 Heap::old_data_space()->MCWriteRelocationInfoToPage(); |
1280 Heap::code_space()->MCWriteRelocationInfoToPage(); | 1314 Heap::code_space()->MCWriteRelocationInfoToPage(); |
1281 Heap::map_space()->MCWriteRelocationInfoToPage(); | 1315 Heap::map_space()->MCWriteRelocationInfoToPage(); |
| 1316 Heap::cell_space()->MCWriteRelocationInfoToPage(); |
1282 } | 1317 } |
1283 | 1318 |
1284 | 1319 |
1285 void MarkCompactCollector::SweepSpaces() { | 1320 void MarkCompactCollector::SweepSpaces() { |
1286 ASSERT(state_ == SWEEP_SPACES); | 1321 ASSERT(state_ == SWEEP_SPACES); |
1287 ASSERT(!IsCompacting()); | 1322 ASSERT(!IsCompacting()); |
1288 // Noncompacting collections simply sweep the spaces to clear the mark | 1323 // Noncompacting collections simply sweep the spaces to clear the mark |
1289 // bits and free the nonlive blocks (for old and map spaces). We sweep | 1324 // bits and free the nonlive blocks (for old and map spaces). We sweep |
1290 // the map space last because freeing non-live maps overwrites them and | 1325 // the map space last because freeing non-live maps overwrites them and |
1291 // the other spaces rely on possibly non-live maps to get the sizes for | 1326 // the other spaces rely on possibly non-live maps to get the sizes for |
1292 // non-live objects. | 1327 // non-live objects. |
1293 SweepSpace(Heap::old_pointer_space(), &DeallocateOldPointerBlock); | 1328 SweepSpace(Heap::old_pointer_space(), &DeallocateOldPointerBlock); |
1294 SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock); | 1329 SweepSpace(Heap::old_data_space(), &DeallocateOldDataBlock); |
1295 SweepSpace(Heap::code_space(), &DeallocateCodeBlock); | 1330 SweepSpace(Heap::code_space(), &DeallocateCodeBlock); |
| 1331 SweepSpace(Heap::cell_space(), &DeallocateCellBlock); |
1296 SweepSpace(Heap::new_space()); | 1332 SweepSpace(Heap::new_space()); |
1297 SweepSpace(Heap::map_space(), &DeallocateMapBlock); | 1333 SweepSpace(Heap::map_space(), &DeallocateMapBlock); |
1298 } | 1334 } |
1299 | 1335 |
1300 | 1336 |
1301 // Iterate the live objects in a range of addresses (eg, a page or a | 1337 // Iterate the live objects in a range of addresses (eg, a page or a |
1302 // semispace). The live regions of the range have been linked into a list. | 1338 // semispace). The live regions of the range have been linked into a list. |
1303 // The first live region is [first_live_start, first_live_end), and the last | 1339 // The first live region is [first_live_start, first_live_end), and the last |
1304 // address in the range is top. The callback function is used to get the | 1340 // address in the range is top. The callback function is used to get the |
1305 // size of each live object. | 1341 // size of each live object. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 private: | 1400 private: |
1365 void UpdatePointer(Object** p) { | 1401 void UpdatePointer(Object** p) { |
1366 if (!(*p)->IsHeapObject()) return; | 1402 if (!(*p)->IsHeapObject()) return; |
1367 | 1403 |
1368 HeapObject* obj = HeapObject::cast(*p); | 1404 HeapObject* obj = HeapObject::cast(*p); |
1369 Address old_addr = obj->address(); | 1405 Address old_addr = obj->address(); |
1370 Address new_addr; | 1406 Address new_addr; |
1371 ASSERT(!Heap::InFromSpace(obj)); | 1407 ASSERT(!Heap::InFromSpace(obj)); |
1372 | 1408 |
1373 if (Heap::new_space()->Contains(obj)) { | 1409 if (Heap::new_space()->Contains(obj)) { |
1374 Address f_addr = Heap::new_space()->FromSpaceLow() + | 1410 Address forwarding_pointer_addr = |
1375 Heap::new_space()->ToSpaceOffsetForAddress(old_addr); | 1411 Heap::new_space()->FromSpaceLow() + |
1376 new_addr = Memory::Address_at(f_addr); | 1412 Heap::new_space()->ToSpaceOffsetForAddress(old_addr); |
| 1413 new_addr = Memory::Address_at(forwarding_pointer_addr); |
1377 | 1414 |
1378 #ifdef DEBUG | 1415 #ifdef DEBUG |
1379 ASSERT(Heap::old_pointer_space()->Contains(new_addr) || | 1416 ASSERT(Heap::old_pointer_space()->Contains(new_addr) || |
1380 Heap::old_data_space()->Contains(new_addr) || | 1417 Heap::old_data_space()->Contains(new_addr) || |
1381 Heap::code_space()->Contains(new_addr) || | 1418 Heap::new_space()->FromSpaceContains(new_addr) || |
1382 Heap::new_space()->FromSpaceContains(new_addr)); | 1419 Heap::lo_space()->Contains(HeapObject::FromAddress(new_addr))); |
1383 | 1420 |
1384 if (Heap::new_space()->FromSpaceContains(new_addr)) { | 1421 if (Heap::new_space()->FromSpaceContains(new_addr)) { |
1385 ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <= | 1422 ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <= |
1386 Heap::new_space()->ToSpaceOffsetForAddress(old_addr)); | 1423 Heap::new_space()->ToSpaceOffsetForAddress(old_addr)); |
1387 } | 1424 } |
1388 #endif | 1425 #endif |
1389 | 1426 |
1390 } else if (Heap::lo_space()->Contains(obj)) { | 1427 } else if (Heap::lo_space()->Contains(obj)) { |
1391 // Don't move objects in the large object space. | 1428 // Don't move objects in the large object space. |
1392 return; | 1429 return; |
1393 | 1430 |
1394 } else { | 1431 } else { |
1395 ASSERT(Heap::old_pointer_space()->Contains(obj) || | 1432 #ifdef DEBUG |
1396 Heap::old_data_space()->Contains(obj) || | 1433 PagedSpaces spaces; |
1397 Heap::code_space()->Contains(obj) || | 1434 PagedSpace* original_space = spaces.next(); |
1398 Heap::map_space()->Contains(obj)); | 1435 while (original_space != NULL) { |
1399 | 1436 if (original_space->Contains(obj)) break; |
| 1437 original_space = spaces.next(); |
| 1438 } |
| 1439 ASSERT(original_space != NULL); |
| 1440 #endif |
1400 new_addr = MarkCompactCollector::GetForwardingAddressInOldSpace(obj); | 1441 new_addr = MarkCompactCollector::GetForwardingAddressInOldSpace(obj); |
1401 ASSERT(Heap::old_pointer_space()->Contains(new_addr) || | 1442 ASSERT(original_space->Contains(new_addr)); |
1402 Heap::old_data_space()->Contains(new_addr) || | 1443 ASSERT(original_space->MCSpaceOffsetForAddress(new_addr) <= |
1403 Heap::code_space()->Contains(new_addr) || | 1444 original_space->MCSpaceOffsetForAddress(old_addr)); |
1404 Heap::map_space()->Contains(new_addr)); | |
1405 | |
1406 #ifdef DEBUG | |
1407 if (Heap::old_pointer_space()->Contains(obj)) { | |
1408 ASSERT(Heap::old_pointer_space()->MCSpaceOffsetForAddress(new_addr) <= | |
1409 Heap::old_pointer_space()->MCSpaceOffsetForAddress(old_addr)); | |
1410 } else if (Heap::old_data_space()->Contains(obj)) { | |
1411 ASSERT(Heap::old_data_space()->MCSpaceOffsetForAddress(new_addr) <= | |
1412 Heap::old_data_space()->MCSpaceOffsetForAddress(old_addr)); | |
1413 } else if (Heap::code_space()->Contains(obj)) { | |
1414 ASSERT(Heap::code_space()->MCSpaceOffsetForAddress(new_addr) <= | |
1415 Heap::code_space()->MCSpaceOffsetForAddress(old_addr)); | |
1416 } else { | |
1417 ASSERT(Heap::map_space()->MCSpaceOffsetForAddress(new_addr) <= | |
1418 Heap::map_space()->MCSpaceOffsetForAddress(old_addr)); | |
1419 } | |
1420 #endif | |
1421 } | 1445 } |
1422 | 1446 |
1423 *p = HeapObject::FromAddress(new_addr); | 1447 *p = HeapObject::FromAddress(new_addr); |
1424 | 1448 |
1425 #ifdef DEBUG | 1449 #ifdef DEBUG |
1426 if (FLAG_gc_verbose) { | 1450 if (FLAG_gc_verbose) { |
1427 PrintF("update %p : %p -> %p\n", | 1451 PrintF("update %p : %p -> %p\n", |
1428 reinterpret_cast<Address>(p), old_addr, new_addr); | 1452 reinterpret_cast<Address>(p), old_addr, new_addr); |
1429 } | 1453 } |
1430 #endif | 1454 #endif |
(...skipping 11 matching lines...) Expand all Loading... |
1442 GlobalHandles::IterateWeakRoots(&updating_visitor); | 1466 GlobalHandles::IterateWeakRoots(&updating_visitor); |
1443 | 1467 |
1444 int live_maps = IterateLiveObjects(Heap::map_space(), | 1468 int live_maps = IterateLiveObjects(Heap::map_space(), |
1445 &UpdatePointersInOldObject); | 1469 &UpdatePointersInOldObject); |
1446 int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(), | 1470 int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(), |
1447 &UpdatePointersInOldObject); | 1471 &UpdatePointersInOldObject); |
1448 int live_data_olds = IterateLiveObjects(Heap::old_data_space(), | 1472 int live_data_olds = IterateLiveObjects(Heap::old_data_space(), |
1449 &UpdatePointersInOldObject); | 1473 &UpdatePointersInOldObject); |
1450 int live_codes = IterateLiveObjects(Heap::code_space(), | 1474 int live_codes = IterateLiveObjects(Heap::code_space(), |
1451 &UpdatePointersInOldObject); | 1475 &UpdatePointersInOldObject); |
| 1476 int live_cells = IterateLiveObjects(Heap::cell_space(), |
| 1477 &UpdatePointersInOldObject); |
1452 int live_news = IterateLiveObjects(Heap::new_space(), | 1478 int live_news = IterateLiveObjects(Heap::new_space(), |
1453 &UpdatePointersInNewObject); | 1479 &UpdatePointersInNewObject); |
1454 | 1480 |
1455 // Large objects do not move, the map word can be updated directly. | 1481 // Large objects do not move, the map word can be updated directly. |
1456 LargeObjectIterator it(Heap::lo_space()); | 1482 LargeObjectIterator it(Heap::lo_space()); |
1457 while (it.has_next()) UpdatePointersInNewObject(it.next()); | 1483 while (it.has_next()) UpdatePointersInNewObject(it.next()); |
1458 | 1484 |
1459 USE(live_maps); | 1485 USE(live_maps); |
1460 USE(live_pointer_olds); | 1486 USE(live_pointer_olds); |
1461 USE(live_data_olds); | 1487 USE(live_data_olds); |
1462 USE(live_codes); | 1488 USE(live_codes); |
| 1489 USE(live_cells); |
1463 USE(live_news); | 1490 USE(live_news); |
1464 | |
1465 #ifdef DEBUG | |
1466 ASSERT(live_maps == live_map_objects_); | 1491 ASSERT(live_maps == live_map_objects_); |
1467 ASSERT(live_data_olds == live_old_data_objects_); | 1492 ASSERT(live_data_olds == live_old_data_objects_); |
1468 ASSERT(live_pointer_olds == live_old_pointer_objects_); | 1493 ASSERT(live_pointer_olds == live_old_pointer_objects_); |
1469 ASSERT(live_codes == live_code_objects_); | 1494 ASSERT(live_codes == live_code_objects_); |
| 1495 ASSERT(live_cells == live_cell_objects_); |
1470 ASSERT(live_news == live_young_objects_); | 1496 ASSERT(live_news == live_young_objects_); |
1471 #endif | |
1472 } | 1497 } |
1473 | 1498 |
1474 | 1499 |
1475 int MarkCompactCollector::UpdatePointersInNewObject(HeapObject* obj) { | 1500 int MarkCompactCollector::UpdatePointersInNewObject(HeapObject* obj) { |
1476 // Keep old map pointers | 1501 // Keep old map pointers |
1477 Map* old_map = obj->map(); | 1502 Map* old_map = obj->map(); |
1478 ASSERT(old_map->IsHeapObject()); | 1503 ASSERT(old_map->IsHeapObject()); |
1479 | 1504 |
1480 Address forwarded = GetForwardingAddressInOldSpace(old_map); | 1505 Address forwarded = GetForwardingAddressInOldSpace(old_map); |
1481 | 1506 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1582 state_ = RELOCATE_OBJECTS; | 1607 state_ = RELOCATE_OBJECTS; |
1583 #endif | 1608 #endif |
1584 // Relocates objects, always relocate map objects first. Relocating | 1609 // Relocates objects, always relocate map objects first. Relocating |
1585 // objects in other space relies on map objects to get object size. | 1610 // objects in other space relies on map objects to get object size. |
1586 int live_maps = IterateLiveObjects(Heap::map_space(), &RelocateMapObject); | 1611 int live_maps = IterateLiveObjects(Heap::map_space(), &RelocateMapObject); |
1587 int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(), | 1612 int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(), |
1588 &RelocateOldPointerObject); | 1613 &RelocateOldPointerObject); |
1589 int live_data_olds = IterateLiveObjects(Heap::old_data_space(), | 1614 int live_data_olds = IterateLiveObjects(Heap::old_data_space(), |
1590 &RelocateOldDataObject); | 1615 &RelocateOldDataObject); |
1591 int live_codes = IterateLiveObjects(Heap::code_space(), &RelocateCodeObject); | 1616 int live_codes = IterateLiveObjects(Heap::code_space(), &RelocateCodeObject); |
| 1617 int live_cells = IterateLiveObjects(Heap::cell_space(), &RelocateCellObject); |
1592 int live_news = IterateLiveObjects(Heap::new_space(), &RelocateNewObject); | 1618 int live_news = IterateLiveObjects(Heap::new_space(), &RelocateNewObject); |
1593 | 1619 |
1594 USE(live_maps); | 1620 USE(live_maps); |
1595 USE(live_data_olds); | 1621 USE(live_data_olds); |
1596 USE(live_pointer_olds); | 1622 USE(live_pointer_olds); |
1597 USE(live_codes); | 1623 USE(live_codes); |
| 1624 USE(live_cells); |
1598 USE(live_news); | 1625 USE(live_news); |
1599 #ifdef DEBUG | |
1600 ASSERT(live_maps == live_map_objects_); | 1626 ASSERT(live_maps == live_map_objects_); |
1601 ASSERT(live_data_olds == live_old_data_objects_); | 1627 ASSERT(live_data_olds == live_old_data_objects_); |
1602 ASSERT(live_pointer_olds == live_old_pointer_objects_); | 1628 ASSERT(live_pointer_olds == live_old_pointer_objects_); |
1603 ASSERT(live_codes == live_code_objects_); | 1629 ASSERT(live_codes == live_code_objects_); |
| 1630 ASSERT(live_cells == live_cell_objects_); |
1604 ASSERT(live_news == live_young_objects_); | 1631 ASSERT(live_news == live_young_objects_); |
1605 #endif | |
1606 | 1632 |
1607 // Notify code object in LO to convert IC target to address | 1633 // Notify code object in LO to convert IC target to address |
1608 // This must happen after lo_space_->Compact | 1634 // This must happen after lo_space_->Compact |
1609 LargeObjectIterator it(Heap::lo_space()); | 1635 LargeObjectIterator it(Heap::lo_space()); |
1610 while (it.has_next()) { ConvertCodeICTargetToAddress(it.next()); } | 1636 while (it.has_next()) { ConvertCodeICTargetToAddress(it.next()); } |
1611 | 1637 |
1612 // Flips from and to spaces | 1638 // Flip from and to spaces |
1613 Heap::new_space()->Flip(); | 1639 Heap::new_space()->Flip(); |
1614 | 1640 |
1615 // Sets age_mark to bottom in to space | 1641 // Set age_mark to bottom in to space |
1616 Address mark = Heap::new_space()->bottom(); | 1642 Address mark = Heap::new_space()->bottom(); |
1617 Heap::new_space()->set_age_mark(mark); | 1643 Heap::new_space()->set_age_mark(mark); |
1618 | 1644 |
1619 Heap::new_space()->MCCommitRelocationInfo(); | 1645 Heap::new_space()->MCCommitRelocationInfo(); |
1620 #ifdef DEBUG | 1646 #ifdef DEBUG |
1621 // It is safe to write to the remembered sets as remembered sets on a | 1647 // It is safe to write to the remembered sets as remembered sets on a |
1622 // page-by-page basis after committing the m-c forwarding pointer. | 1648 // page-by-page basis after committing the m-c forwarding pointer. |
1623 Page::set_rset_state(Page::IN_USE); | 1649 Page::set_rset_state(Page::IN_USE); |
1624 #endif | 1650 #endif |
1625 PagedSpaces spaces; | 1651 PagedSpaces spaces; |
1626 while (PagedSpace* space = spaces.next()) space->MCCommitRelocationInfo(); | 1652 while (PagedSpace* space = spaces.next()) space->MCCommitRelocationInfo(); |
1627 } | 1653 } |
1628 | 1654 |
1629 | 1655 |
1630 int MarkCompactCollector::ConvertCodeICTargetToAddress(HeapObject* obj) { | 1656 int MarkCompactCollector::ConvertCodeICTargetToAddress(HeapObject* obj) { |
1631 if (obj->IsCode()) { | 1657 if (obj->IsCode()) { |
1632 Code::cast(obj)->ConvertICTargetsFromObjectToAddress(); | 1658 Code::cast(obj)->ConvertICTargetsFromObjectToAddress(); |
1633 } | 1659 } |
1634 return obj->Size(); | 1660 return obj->Size(); |
1635 } | 1661 } |
1636 | 1662 |
1637 | 1663 |
1638 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { | 1664 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { |
1639 // decode map pointer (forwarded address) | 1665 // Recover map pointer. |
1640 MapWord encoding = obj->map_word(); | 1666 MapWord encoding = obj->map_word(); |
1641 Address map_addr = encoding.DecodeMapAddress(Heap::map_space()); | 1667 Address map_addr = encoding.DecodeMapAddress(Heap::map_space()); |
1642 ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr))); | 1668 ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr))); |
1643 | 1669 |
1644 // Get forwarding address before resetting map pointer | 1670 // Get forwarding address before resetting map pointer |
1645 Address new_addr = GetForwardingAddressInOldSpace(obj); | 1671 Address new_addr = GetForwardingAddressInOldSpace(obj); |
1646 | 1672 |
1647 // recover map pointer | 1673 // Reset map pointer. The meta map object may not be copied yet so |
| 1674 // Map::cast does not yet work. |
1648 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr))); | 1675 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr))); |
1649 | 1676 |
1650 // The meta map object may not be copied yet. | |
1651 Address old_addr = obj->address(); | 1677 Address old_addr = obj->address(); |
1652 | 1678 |
1653 if (new_addr != old_addr) { | 1679 if (new_addr != old_addr) { |
1654 memmove(new_addr, old_addr, Map::kSize); // copy contents | 1680 memmove(new_addr, old_addr, Map::kSize); // copy contents |
1655 } | 1681 } |
1656 | 1682 |
1657 #ifdef DEBUG | 1683 #ifdef DEBUG |
1658 if (FLAG_gc_verbose) { | 1684 if (FLAG_gc_verbose) { |
1659 PrintF("relocate %p -> %p\n", old_addr, new_addr); | 1685 PrintF("relocate %p -> %p\n", old_addr, new_addr); |
1660 } | 1686 } |
1661 #endif | 1687 #endif |
1662 | 1688 |
1663 return Map::kSize; | 1689 return Map::kSize; |
1664 } | 1690 } |
1665 | 1691 |
1666 | 1692 |
1667 static inline int RelocateOldObject(HeapObject* obj, | 1693 static inline int RestoreMap(HeapObject* obj, |
1668 OldSpace* space, | 1694 PagedSpace* space, |
1669 Address new_addr, | 1695 Address new_addr, |
1670 Address map_addr) { | 1696 Address map_addr) { |
1671 // recover map pointer | 1697 // This must be a non-map object, and the function relies on the |
1672 obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr))); | 1698 // assumption that the Map space is compacted before the other paged |
| 1699 // spaces (see RelocateObjects). |
1673 | 1700 |
1674 // This is a non-map object, it relies on the assumption that the Map space | 1701 // Reset map pointer. |
1675 // is compacted before the Old space (see RelocateObjects). | 1702 obj->set_map(Map::cast(HeapObject::FromAddress(map_addr))); |
| 1703 |
1676 int obj_size = obj->Size(); | 1704 int obj_size = obj->Size(); |
1677 ASSERT_OBJECT_SIZE(obj_size); | 1705 ASSERT_OBJECT_SIZE(obj_size); |
1678 | 1706 |
1679 ASSERT(space->MCSpaceOffsetForAddress(new_addr) <= | 1707 ASSERT(space->MCSpaceOffsetForAddress(new_addr) <= |
1680 space->MCSpaceOffsetForAddress(obj->address())); | 1708 space->MCSpaceOffsetForAddress(obj->address())); |
1681 | 1709 |
1682 space->MCAdjustRelocationEnd(new_addr, obj_size); | |
1683 | |
1684 #ifdef DEBUG | 1710 #ifdef DEBUG |
1685 if (FLAG_gc_verbose) { | 1711 if (FLAG_gc_verbose) { |
1686 PrintF("relocate %p -> %p\n", obj->address(), new_addr); | 1712 PrintF("relocate %p -> %p\n", obj->address(), new_addr); |
1687 } | 1713 } |
1688 #endif | 1714 #endif |
1689 | 1715 |
1690 return obj_size; | 1716 return obj_size; |
1691 } | 1717 } |
1692 | 1718 |
1693 | 1719 |
1694 int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj, | 1720 int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj, |
1695 OldSpace* space) { | 1721 PagedSpace* space) { |
1696 // decode map pointer (forwarded address) | 1722 // Recover map pointer. |
1697 MapWord encoding = obj->map_word(); | 1723 MapWord encoding = obj->map_word(); |
1698 Address map_addr = encoding.DecodeMapAddress(Heap::map_space()); | 1724 Address map_addr = encoding.DecodeMapAddress(Heap::map_space()); |
1699 ASSERT(Heap::map_space()->Contains(map_addr)); | 1725 ASSERT(Heap::map_space()->Contains(map_addr)); |
1700 | 1726 |
1701 // Get forwarding address before resetting map pointer | 1727 // Get forwarding address before resetting map pointer. |
1702 Address new_addr = GetForwardingAddressInOldSpace(obj); | 1728 Address new_addr = GetForwardingAddressInOldSpace(obj); |
1703 | 1729 |
1704 int obj_size = RelocateOldObject(obj, space, new_addr, map_addr); | 1730 // Reset the map pointer. |
| 1731 int obj_size = RestoreMap(obj, space, new_addr, map_addr); |
1705 | 1732 |
1706 Address old_addr = obj->address(); | 1733 Address old_addr = obj->address(); |
1707 | 1734 |
1708 if (new_addr != old_addr) { | 1735 if (new_addr != old_addr) { |
1709 memmove(new_addr, old_addr, obj_size); // copy contents | 1736 memmove(new_addr, old_addr, obj_size); // Copy contents |
1710 } | 1737 } |
1711 | 1738 |
1712 ASSERT(!HeapObject::FromAddress(new_addr)->IsCode()); | 1739 ASSERT(!HeapObject::FromAddress(new_addr)->IsCode()); |
1713 | 1740 |
1714 return obj_size; | 1741 return obj_size; |
1715 } | 1742 } |
1716 | 1743 |
1717 | 1744 |
1718 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { | 1745 int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) { |
1719 return RelocateOldNonCodeObject(obj, Heap::old_pointer_space()); | 1746 return RelocateOldNonCodeObject(obj, Heap::old_pointer_space()); |
1720 } | 1747 } |
1721 | 1748 |
1722 | 1749 |
1723 int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) { | 1750 int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) { |
1724 return RelocateOldNonCodeObject(obj, Heap::old_data_space()); | 1751 return RelocateOldNonCodeObject(obj, Heap::old_data_space()); |
1725 } | 1752 } |
1726 | 1753 |
1727 | 1754 |
| 1755 int MarkCompactCollector::RelocateCellObject(HeapObject* obj) { |
| 1756 return RelocateOldNonCodeObject(obj, Heap::cell_space()); |
| 1757 } |
| 1758 |
| 1759 |
1728 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) { | 1760 int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) { |
1729 // decode map pointer (forwarded address) | 1761 // Recover map pointer. |
1730 MapWord encoding = obj->map_word(); | 1762 MapWord encoding = obj->map_word(); |
1731 Address map_addr = encoding.DecodeMapAddress(Heap::map_space()); | 1763 Address map_addr = encoding.DecodeMapAddress(Heap::map_space()); |
1732 ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr))); | 1764 ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr))); |
1733 | 1765 |
1734 // Get forwarding address before resetting map pointer | 1766 // Get forwarding address before resetting map pointer |
1735 Address new_addr = GetForwardingAddressInOldSpace(obj); | 1767 Address new_addr = GetForwardingAddressInOldSpace(obj); |
1736 | 1768 |
1737 int obj_size = RelocateOldObject(obj, Heap::code_space(), new_addr, map_addr); | 1769 // Reset the map pointer. |
| 1770 int obj_size = RestoreMap(obj, Heap::code_space(), new_addr, map_addr); |
1738 | 1771 |
1739 // convert inline cache target to address using old address | 1772 // Convert inline cache target to address using old address. |
1740 if (obj->IsCode()) { | 1773 if (obj->IsCode()) { |
1741 // convert target to address first related to old_address | |
1742 Code::cast(obj)->ConvertICTargetsFromObjectToAddress(); | 1774 Code::cast(obj)->ConvertICTargetsFromObjectToAddress(); |
1743 } | 1775 } |
1744 | 1776 |
1745 Address old_addr = obj->address(); | 1777 Address old_addr = obj->address(); |
1746 | 1778 |
1747 if (new_addr != old_addr) { | 1779 if (new_addr != old_addr) { |
1748 memmove(new_addr, old_addr, obj_size); // copy contents | 1780 memmove(new_addr, old_addr, obj_size); // Copy contents. |
1749 } | 1781 } |
1750 | 1782 |
1751 HeapObject* copied_to = HeapObject::FromAddress(new_addr); | 1783 HeapObject* copied_to = HeapObject::FromAddress(new_addr); |
1752 if (copied_to->IsCode()) { | 1784 if (copied_to->IsCode()) { |
1753 // may also update inline cache target. | 1785 // May also update inline cache target. |
1754 Code::cast(copied_to)->Relocate(new_addr - old_addr); | 1786 Code::cast(copied_to)->Relocate(new_addr - old_addr); |
1755 // Notify the logger that compiled code has moved. | 1787 // Notify the logger that compiled code has moved. |
1756 LOG(CodeMoveEvent(old_addr, new_addr)); | 1788 LOG(CodeMoveEvent(old_addr, new_addr)); |
1757 } | 1789 } |
1758 | 1790 |
1759 return obj_size; | 1791 return obj_size; |
1760 } | 1792 } |
1761 | 1793 |
1762 | 1794 |
1763 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) { | 1795 int MarkCompactCollector::RelocateNewObject(HeapObject* obj) { |
1764 int obj_size = obj->Size(); | 1796 int obj_size = obj->Size(); |
1765 | 1797 |
1766 // Get forwarding address | 1798 // Get forwarding address |
1767 Address old_addr = obj->address(); | 1799 Address old_addr = obj->address(); |
1768 int offset = Heap::new_space()->ToSpaceOffsetForAddress(old_addr); | 1800 int offset = Heap::new_space()->ToSpaceOffsetForAddress(old_addr); |
1769 | 1801 |
1770 Address new_addr = | 1802 Address new_addr = |
1771 Memory::Address_at(Heap::new_space()->FromSpaceLow() + offset); | 1803 Memory::Address_at(Heap::new_space()->FromSpaceLow() + offset); |
1772 | 1804 |
| 1805 #ifdef DEBUG |
1773 if (Heap::new_space()->FromSpaceContains(new_addr)) { | 1806 if (Heap::new_space()->FromSpaceContains(new_addr)) { |
1774 ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <= | 1807 ASSERT(Heap::new_space()->FromSpaceOffsetForAddress(new_addr) <= |
1775 Heap::new_space()->ToSpaceOffsetForAddress(old_addr)); | 1808 Heap::new_space()->ToSpaceOffsetForAddress(old_addr)); |
1776 } else { | 1809 } else { |
1777 OldSpace* target_space = Heap::TargetSpace(obj); | 1810 ASSERT(Heap::TargetSpace(obj) == Heap::old_pointer_space() || |
1778 ASSERT(target_space == Heap::old_pointer_space() || | 1811 Heap::TargetSpace(obj) == Heap::old_data_space()); |
1779 target_space == Heap::old_data_space()); | |
1780 target_space->MCAdjustRelocationEnd(new_addr, obj_size); | |
1781 } | 1812 } |
| 1813 #endif |
1782 | 1814 |
1783 // New and old addresses cannot overlap. | 1815 // New and old addresses cannot overlap. |
1784 memcpy(reinterpret_cast<void*>(new_addr), | 1816 memcpy(reinterpret_cast<void*>(new_addr), |
1785 reinterpret_cast<void*>(old_addr), | 1817 reinterpret_cast<void*>(old_addr), |
1786 obj_size); | 1818 obj_size); |
1787 | 1819 |
1788 #ifdef DEBUG | 1820 #ifdef DEBUG |
1789 if (FLAG_gc_verbose) { | 1821 if (FLAG_gc_verbose) { |
1790 PrintF("relocate %p -> %p\n", old_addr, new_addr); | 1822 PrintF("relocate %p -> %p\n", old_addr, new_addr); |
1791 } | 1823 } |
1792 #endif | 1824 #endif |
1793 | 1825 |
1794 return obj_size; | 1826 return obj_size; |
1795 } | 1827 } |
1796 | 1828 |
1797 | 1829 |
1798 // ------------------------------------------------------------------------- | 1830 // ------------------------------------------------------------------------- |
1799 // Phase 5: rebuild remembered sets | 1831 // Phase 5: rebuild remembered sets |
1800 | 1832 |
1801 void MarkCompactCollector::RebuildRSets() { | 1833 void MarkCompactCollector::RebuildRSets() { |
1802 #ifdef DEBUG | 1834 #ifdef DEBUG |
1803 ASSERT(state_ == RELOCATE_OBJECTS); | 1835 ASSERT(state_ == RELOCATE_OBJECTS); |
1804 state_ = REBUILD_RSETS; | 1836 state_ = REBUILD_RSETS; |
1805 #endif | 1837 #endif |
1806 Heap::RebuildRSets(); | 1838 Heap::RebuildRSets(); |
1807 } | 1839 } |
1808 | 1840 |
1809 } } // namespace v8::internal | 1841 } } // namespace v8::internal |
OLD | NEW |