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

Side by Side Diff: src/mark-compact.cc

Issue 203070: Stop "cooking" targets of jumps and calls in code objects. Do not convert ju... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap.cc ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 void VisitPointers(Object** start, Object** end) { 258 void VisitPointers(Object** start, Object** end) {
259 // Mark all objects pointed to in [start, end). 259 // Mark all objects pointed to in [start, end).
260 const int kMinRangeForMarkingRecursion = 64; 260 const int kMinRangeForMarkingRecursion = 64;
261 if (end - start >= kMinRangeForMarkingRecursion) { 261 if (end - start >= kMinRangeForMarkingRecursion) {
262 if (VisitUnmarkedObjects(start, end)) return; 262 if (VisitUnmarkedObjects(start, end)) return;
263 // We are close to a stack overflow, so just mark the objects. 263 // We are close to a stack overflow, so just mark the objects.
264 } 264 }
265 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); 265 for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
266 } 266 }
267 267
268 void BeginCodeIteration(Code* code) {
269 // When iterating over a code object during marking
270 // ic targets are derived pointers.
271 ASSERT(code->ic_flag() == Code::IC_TARGET_IS_ADDRESS);
272 }
273
274 void EndCodeIteration(Code* code) {
275 // If this is a compacting collection, set ic targets
276 // are pointing to object headers.
277 if (IsCompacting()) code->set_ic_flag(Code::IC_TARGET_IS_OBJECT);
278 }
279
280 void VisitCodeTarget(RelocInfo* rinfo) { 268 void VisitCodeTarget(RelocInfo* rinfo) {
281 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); 269 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
282 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); 270 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address());
283 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { 271 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) {
284 IC::Clear(rinfo->pc()); 272 IC::Clear(rinfo->pc());
285 // Please note targets for cleared inline cached do not have to be 273 // Please note targets for cleared inline cached do not have to be
286 // marked since they are contained in Heap::non_monomorphic_cache(). 274 // marked since they are contained in Heap::non_monomorphic_cache().
287 } else { 275 } else {
288 MarkCompactCollector::MarkObject(code); 276 MarkCompactCollector::MarkObject(code);
289 } 277 }
290 if (IsCompacting()) {
291 // When compacting we convert the target to a real object pointer.
292 code = Code::GetCodeFromTargetAddress(rinfo->target_address());
293 rinfo->set_target_object(code);
294 }
295 } 278 }
296 279
297 void VisitDebugTarget(RelocInfo* rinfo) { 280 void VisitDebugTarget(RelocInfo* rinfo) {
298 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) && 281 ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) &&
299 rinfo->IsCallInstruction()); 282 rinfo->IsCallInstruction());
300 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); 283 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address());
301 MarkCompactCollector::MarkObject(code); 284 MarkCompactCollector::MarkObject(code);
302 // When compacting we convert the call to a real object pointer. 285 // When compacting we convert the call to a real object pointer.
303 if (IsCompacting()) rinfo->set_call_object(code); 286 if (IsCompacting()) rinfo->set_call_object(code);
304 } 287 }
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
1180 Address free_start = NULL; 1163 Address free_start = NULL;
1181 HeapObject* object; 1164 HeapObject* object;
1182 1165
1183 for (Address current = p->ObjectAreaStart(); 1166 for (Address current = p->ObjectAreaStart();
1184 current < p->AllocationTop(); 1167 current < p->AllocationTop();
1185 current += object->Size()) { 1168 current += object->Size()) {
1186 object = HeapObject::FromAddress(current); 1169 object = HeapObject::FromAddress(current);
1187 if (object->IsMarked()) { 1170 if (object->IsMarked()) {
1188 object->ClearMark(); 1171 object->ClearMark();
1189 MarkCompactCollector::tracer()->decrement_marked_count(); 1172 MarkCompactCollector::tracer()->decrement_marked_count();
1190 if (MarkCompactCollector::IsCompacting() && object->IsCode()) {
1191 // If this is compacting collection marked code objects have had
1192 // their IC targets converted to objects.
1193 // They need to be converted back to addresses.
1194 Code::cast(object)->ConvertICTargetsFromObjectToAddress();
1195 }
1196 if (!is_previous_alive) { // Transition from free to live. 1173 if (!is_previous_alive) { // Transition from free to live.
1197 dealloc(free_start, current - free_start); 1174 dealloc(free_start, current - free_start);
1198 is_previous_alive = true; 1175 is_previous_alive = true;
1199 } 1176 }
1200 } else { 1177 } else {
1201 if (object->IsCode()) { 1178 if (object->IsCode()) {
1202 // Notify the logger that compiled code has been collected. 1179 // Notify the logger that compiled code has been collected.
1203 LOG(CodeDeleteEvent(Code::cast(object)->address())); 1180 LOG(CodeDeleteEvent(Code::cast(object)->address()));
1204 } 1181 }
1205 if (is_previous_alive) { // Transition from live to free. 1182 if (is_previous_alive) { // Transition from live to free.
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 public: 1368 public:
1392 void VisitPointer(Object** p) { 1369 void VisitPointer(Object** p) {
1393 UpdatePointer(p); 1370 UpdatePointer(p);
1394 } 1371 }
1395 1372
1396 void VisitPointers(Object** start, Object** end) { 1373 void VisitPointers(Object** start, Object** end) {
1397 // Mark all HeapObject pointers in [start, end) 1374 // Mark all HeapObject pointers in [start, end)
1398 for (Object** p = start; p < end; p++) UpdatePointer(p); 1375 for (Object** p = start; p < end; p++) UpdatePointer(p);
1399 } 1376 }
1400 1377
1378 void VisitCodeTarget(RelocInfo* rinfo) {
1379 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
1380 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
1381 VisitPointer(&target);
1382 rinfo->set_target_address(
1383 reinterpret_cast<Code*>(target)->instruction_start());
1384 }
1385
1401 private: 1386 private:
1402 void UpdatePointer(Object** p) { 1387 void UpdatePointer(Object** p) {
1403 if (!(*p)->IsHeapObject()) return; 1388 if (!(*p)->IsHeapObject()) return;
1404 1389
1405 HeapObject* obj = HeapObject::cast(*p); 1390 HeapObject* obj = HeapObject::cast(*p);
1406 Address old_addr = obj->address(); 1391 Address old_addr = obj->address();
1407 Address new_addr; 1392 Address new_addr;
1408 ASSERT(!Heap::InFromSpace(obj)); 1393 ASSERT(!Heap::InFromSpace(obj));
1409 1394
1410 if (Heap::new_space()->Contains(obj)) { 1395 if (Heap::new_space()->Contains(obj)) {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 USE(live_codes); 1609 USE(live_codes);
1625 USE(live_cells); 1610 USE(live_cells);
1626 USE(live_news); 1611 USE(live_news);
1627 ASSERT(live_maps == live_map_objects_); 1612 ASSERT(live_maps == live_map_objects_);
1628 ASSERT(live_data_olds == live_old_data_objects_); 1613 ASSERT(live_data_olds == live_old_data_objects_);
1629 ASSERT(live_pointer_olds == live_old_pointer_objects_); 1614 ASSERT(live_pointer_olds == live_old_pointer_objects_);
1630 ASSERT(live_codes == live_code_objects_); 1615 ASSERT(live_codes == live_code_objects_);
1631 ASSERT(live_cells == live_cell_objects_); 1616 ASSERT(live_cells == live_cell_objects_);
1632 ASSERT(live_news == live_young_objects_); 1617 ASSERT(live_news == live_young_objects_);
1633 1618
1634 // Notify code object in LO to convert IC target to address
1635 // This must happen after lo_space_->Compact
1636 LargeObjectIterator it(Heap::lo_space());
1637 while (it.has_next()) { ConvertCodeICTargetToAddress(it.next()); }
1638
1639 // Flip from and to spaces 1619 // Flip from and to spaces
1640 Heap::new_space()->Flip(); 1620 Heap::new_space()->Flip();
1641 1621
1642 // Set age_mark to bottom in to space 1622 // Set age_mark to bottom in to space
1643 Address mark = Heap::new_space()->bottom(); 1623 Address mark = Heap::new_space()->bottom();
1644 Heap::new_space()->set_age_mark(mark); 1624 Heap::new_space()->set_age_mark(mark);
1645 1625
1646 Heap::new_space()->MCCommitRelocationInfo(); 1626 Heap::new_space()->MCCommitRelocationInfo();
1647 #ifdef DEBUG 1627 #ifdef DEBUG
1648 // It is safe to write to the remembered sets as remembered sets on a 1628 // It is safe to write to the remembered sets as remembered sets on a
1649 // page-by-page basis after committing the m-c forwarding pointer. 1629 // page-by-page basis after committing the m-c forwarding pointer.
1650 Page::set_rset_state(Page::IN_USE); 1630 Page::set_rset_state(Page::IN_USE);
1651 #endif 1631 #endif
1652 PagedSpaces spaces; 1632 PagedSpaces spaces;
1653 while (PagedSpace* space = spaces.next()) space->MCCommitRelocationInfo(); 1633 while (PagedSpace* space = spaces.next()) space->MCCommitRelocationInfo();
1654 } 1634 }
1655 1635
1656 1636
1657 int MarkCompactCollector::ConvertCodeICTargetToAddress(HeapObject* obj) {
1658 if (obj->IsCode()) {
1659 Code::cast(obj)->ConvertICTargetsFromObjectToAddress();
1660 }
1661 return obj->Size();
1662 }
1663
1664
1665 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { 1637 int MarkCompactCollector::RelocateMapObject(HeapObject* obj) {
1666 // Recover map pointer. 1638 // Recover map pointer.
1667 MapWord encoding = obj->map_word(); 1639 MapWord encoding = obj->map_word();
1668 Address map_addr = encoding.DecodeMapAddress(Heap::map_space()); 1640 Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
1669 ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr))); 1641 ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));
1670 1642
1671 // Get forwarding address before resetting map pointer 1643 // Get forwarding address before resetting map pointer
1672 Address new_addr = GetForwardingAddressInOldSpace(obj); 1644 Address new_addr = GetForwardingAddressInOldSpace(obj);
1673 1645
1674 // Reset map pointer. The meta map object may not be copied yet so 1646 // Reset map pointer. The meta map object may not be copied yet so
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 MapWord encoding = obj->map_word(); 1735 MapWord encoding = obj->map_word();
1764 Address map_addr = encoding.DecodeMapAddress(Heap::map_space()); 1736 Address map_addr = encoding.DecodeMapAddress(Heap::map_space());
1765 ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr))); 1737 ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));
1766 1738
1767 // Get forwarding address before resetting map pointer 1739 // Get forwarding address before resetting map pointer
1768 Address new_addr = GetForwardingAddressInOldSpace(obj); 1740 Address new_addr = GetForwardingAddressInOldSpace(obj);
1769 1741
1770 // Reset the map pointer. 1742 // Reset the map pointer.
1771 int obj_size = RestoreMap(obj, Heap::code_space(), new_addr, map_addr); 1743 int obj_size = RestoreMap(obj, Heap::code_space(), new_addr, map_addr);
1772 1744
1773 // Convert inline cache target to address using old address.
1774 if (obj->IsCode()) {
1775 Code::cast(obj)->ConvertICTargetsFromObjectToAddress();
1776 }
1777
1778 Address old_addr = obj->address(); 1745 Address old_addr = obj->address();
1779 1746
1780 if (new_addr != old_addr) { 1747 if (new_addr != old_addr) {
1781 memmove(new_addr, old_addr, obj_size); // Copy contents. 1748 memmove(new_addr, old_addr, obj_size); // Copy contents.
1782 } 1749 }
1783 1750
1784 HeapObject* copied_to = HeapObject::FromAddress(new_addr); 1751 HeapObject* copied_to = HeapObject::FromAddress(new_addr);
1785 if (copied_to->IsCode()) { 1752 if (copied_to->IsCode()) {
1786 // May also update inline cache target. 1753 // May also update inline cache target.
1787 Code::cast(copied_to)->Relocate(new_addr - old_addr); 1754 Code::cast(copied_to)->Relocate(new_addr - old_addr);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 1800
1834 void MarkCompactCollector::RebuildRSets() { 1801 void MarkCompactCollector::RebuildRSets() {
1835 #ifdef DEBUG 1802 #ifdef DEBUG
1836 ASSERT(state_ == RELOCATE_OBJECTS); 1803 ASSERT(state_ == RELOCATE_OBJECTS);
1837 state_ = REBUILD_RSETS; 1804 state_ = REBUILD_RSETS;
1838 #endif 1805 #endif
1839 Heap::RebuildRSets(); 1806 Heap::RebuildRSets();
1840 } 1807 }
1841 1808
1842 } } // namespace v8::internal 1809 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698