⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mark-compact.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
#endif  }};void MarkCompactCollector::UpdatePointers() {#ifdef DEBUG  ASSERT(state_ == ENCODE_FORWARDING_ADDRESSES);  state_ = UPDATE_POINTERS;#endif  UpdatingVisitor updating_visitor;  Heap::IterateRoots(&updating_visitor);  GlobalHandles::IterateWeakRoots(&updating_visitor);  int live_maps = IterateLiveObjects(Heap::map_space(),                                     &UpdatePointersInOldObject);  int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),                                             &UpdatePointersInOldObject);  int live_data_olds = IterateLiveObjects(Heap::old_data_space(),                                          &UpdatePointersInOldObject);  int live_codes = IterateLiveObjects(Heap::code_space(),                                      &UpdatePointersInOldObject);  int live_news = IterateLiveObjects(Heap::new_space(),                                     &UpdatePointersInNewObject);  // Large objects do not move, the map word can be updated directly.  LargeObjectIterator it(Heap::lo_space());  while (it.has_next()) UpdatePointersInNewObject(it.next());  USE(live_maps);  USE(live_pointer_olds);  USE(live_data_olds);  USE(live_codes);  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_news == live_young_objects_);  if (FLAG_verify_global_gc) VerifyHeapAfterUpdatingPointers();#endif}int MarkCompactCollector::UpdatePointersInNewObject(HeapObject* obj) {  // Keep old map pointers  Map* old_map = obj->map();  ASSERT(old_map->IsHeapObject());  Address forwarded = GetForwardingAddressInOldSpace(old_map);  ASSERT(Heap::map_space()->Contains(old_map));  ASSERT(Heap::map_space()->Contains(forwarded));#ifdef DEBUG  if (FLAG_gc_verbose) {    PrintF("update %p : %p -> %p\n", obj->address(), old_map->address(),           forwarded);  }#endif  // Update the map pointer.  obj->set_map(reinterpret_cast<Map*>(HeapObject::FromAddress(forwarded)));  // We have to compute the object size relying on the old map because  // map objects are not relocated yet.  int obj_size = obj->SizeFromMap(old_map);  // Update pointers in the object body.  UpdatingVisitor updating_visitor;  obj->IterateBody(old_map->instance_type(), obj_size, &updating_visitor);  return obj_size;}int MarkCompactCollector::UpdatePointersInOldObject(HeapObject* obj) {  // Decode the map pointer.  MapWord encoding = obj->map_word();  Address map_addr = encoding.DecodeMapAddress(Heap::map_space());  ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));  // At this point, the first word of map_addr is also encoded, cannot  // cast it to Map* using Map::cast.  Map* map = reinterpret_cast<Map*>(HeapObject::FromAddress(map_addr));  int obj_size = obj->SizeFromMap(map);  InstanceType type = map->instance_type();  // Update map pointer.  Address new_map_addr = GetForwardingAddressInOldSpace(map);  int offset = encoding.DecodeOffset();  obj->set_map_word(MapWord::EncodeAddress(new_map_addr, offset));#ifdef DEBUG  if (FLAG_gc_verbose) {    PrintF("update %p : %p -> %p\n", obj->address(),           map_addr, new_map_addr);  }#endif  // Update pointers in the object body.  UpdatingVisitor updating_visitor;  obj->IterateBody(type, obj_size, &updating_visitor);  return obj_size;}Address MarkCompactCollector::GetForwardingAddressInOldSpace(HeapObject* obj) {  // Object should either in old or map space.  MapWord encoding = obj->map_word();  // Offset to the first live object's forwarding address.  int offset = encoding.DecodeOffset();  Address obj_addr = obj->address();  // Find the first live object's forwarding address.  Page* p = Page::FromAddress(obj_addr);  Address first_forwarded = p->mc_first_forwarded;  // Page start address of forwarded address.  Page* forwarded_page = Page::FromAddress(first_forwarded);  int forwarded_offset = forwarded_page->Offset(first_forwarded);  // Find end of allocation of in the page of first_forwarded.  Address mc_top = forwarded_page->mc_relocation_top;  int mc_top_offset = forwarded_page->Offset(mc_top);  // Check if current object's forward pointer is in the same page  // as the first live object's forwarding pointer  if (forwarded_offset + offset < mc_top_offset) {    // In the same page.    return first_forwarded + offset;  }  // Must be in the next page, NOTE: this may cross chunks.  Page* next_page = forwarded_page->next_page();  ASSERT(next_page->is_valid());  offset -= (mc_top_offset - forwarded_offset);  offset += Page::kObjectStartOffset;  ASSERT_PAGE_OFFSET(offset);  ASSERT(next_page->OffsetToAddress(offset) < next_page->mc_relocation_top);  return next_page->OffsetToAddress(offset);}#ifdef DEBUGvoid MarkCompactCollector::VerifyHeapAfterUpdatingPointers() {  ASSERT(state_ == UPDATE_POINTERS);  AllSpaces spaces;  while (Space* space = spaces.next()) space->Verify();  PagedSpaces paged_spaces;  while (PagedSpace* space = paged_spaces.next()) VerifyPageHeaders(space);}#endif// ----------------------------------------------------------------------------// Phase 4: Relocate objectsvoid MarkCompactCollector::RelocateObjects() {#ifdef DEBUG  ASSERT(state_ == UPDATE_POINTERS);  state_ = RELOCATE_OBJECTS;#endif  // Relocates objects, always relocate map objects first. Relocating  // objects in other space relies on map objects to get object size.  int live_maps = IterateLiveObjects(Heap::map_space(), &RelocateMapObject);  int live_pointer_olds = IterateLiveObjects(Heap::old_pointer_space(),                                             &RelocateOldPointerObject);  int live_data_olds = IterateLiveObjects(Heap::old_data_space(),                                          &RelocateOldDataObject);  int live_codes = IterateLiveObjects(Heap::code_space(), &RelocateCodeObject);  int live_news = IterateLiveObjects(Heap::new_space(), &RelocateNewObject);  USE(live_maps);  USE(live_data_olds);  USE(live_pointer_olds);  USE(live_codes);  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_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  Heap::new_space()->Flip();  // Sets age_mark to bottom in to space  Address mark = Heap::new_space()->bottom();  Heap::new_space()->set_age_mark(mark);  Heap::new_space()->MCCommitRelocationInfo();#ifdef DEBUG  // It is safe to write to the remembered sets as remembered sets on a  // page-by-page basis after committing the m-c forwarding pointer.  Page::set_rset_state(Page::IN_USE);#endif  PagedSpaces spaces;  while (PagedSpace* space = spaces.next()) space->MCCommitRelocationInfo();#ifdef DEBUG  if (FLAG_verify_global_gc) VerifyHeapAfterRelocatingObjects();#endif}int MarkCompactCollector::ConvertCodeICTargetToAddress(HeapObject* obj) {  if (obj->IsCode()) {    Code::cast(obj)->ConvertICTargetsFromObjectToAddress();  }  return obj->Size();}int MarkCompactCollector::RelocateMapObject(HeapObject* obj) {  // decode map pointer (forwarded address)  MapWord encoding = obj->map_word();  Address map_addr = encoding.DecodeMapAddress(Heap::map_space());  ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));  // Get forwarding address before resetting map pointer  Address new_addr = GetForwardingAddressInOldSpace(obj);  // recover map pointer  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) {    memmove(new_addr, old_addr, Map::kSize);  // copy contents  }#ifdef DEBUG  if (FLAG_gc_verbose) {    PrintF("relocate %p -> %p\n", old_addr, new_addr);  }#endif  return Map::kSize;}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)));  // This is a non-map object, it relies on the assumption that the Map space  // is compacted before the Old space (see RelocateObjects).  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);  }#endif  return obj_size;}int MarkCompactCollector::RelocateOldNonCodeObject(HeapObject* obj,                                                   OldSpace* space) {  // decode map pointer (forwarded address)  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  Address new_addr = GetForwardingAddressInOldSpace(obj);  int obj_size = RelocateOldObject(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  }  ASSERT(!HeapObject::FromAddress(new_addr)->IsCode());  return obj_size;}int MarkCompactCollector::RelocateOldPointerObject(HeapObject* obj) {  return RelocateOldNonCodeObject(obj, Heap::old_pointer_space());}int MarkCompactCollector::RelocateOldDataObject(HeapObject* obj) {  return RelocateOldNonCodeObject(obj, Heap::old_data_space());}int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {  // decode map pointer (forwarded address)  MapWord encoding = obj->map_word();  Address map_addr = encoding.DecodeMapAddress(Heap::map_space());  ASSERT(Heap::map_space()->Contains(HeapObject::FromAddress(map_addr)));  // Get forwarding address before resetting map pointer  Address new_addr = GetForwardingAddressInOldSpace(obj);  int obj_size = RelocateOldObject(obj, Heap::code_space(), new_addr, map_addr);  // 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  }  HeapObject* copied_to = HeapObject::FromAddress(new_addr);  if (copied_to->IsCode()) {    // may also update inline cache target.    Code::cast(copied_to)->Relocate(new_addr - old_addr);    // Notify the logger that compile code has moved.    LOG(CodeMoveEvent(old_addr, new_addr));  }  return obj_size;}#ifdef DEBUGclass VerifyCopyingVisitor: public ObjectVisitor { public:  void VisitPointers(Object** start, Object** end) {    for (Object** p = start; p < end; p++) {      MarkCompactCollector::VerifyCopyingObjects(p);    }  }};#endifint MarkCompactCollector::RelocateNewObject(HeapObject* obj) {  int obj_size = obj->Size();  // Get forwarding address  Address old_addr = obj->address();  int offset = Heap::new_space()->ToSpaceOffsetForAddress(old_addr);  Address new_addr =    Memory::Address_at(Heap::new_space()->FromSpaceLow() + offset);  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);  }  // New and old addresses cannot overlap.  memcpy(reinterpret_cast<void*>(new_addr),         reinterpret_cast<void*>(old_addr),         obj_size);#ifdef DEBUG  if (FLAG_gc_verbose) {    PrintF("relocate %p -> %p\n", old_addr, new_addr);  }  if (FLAG_verify_global_gc) {    VerifyCopyingVisitor v;    HeapObject* copied_to = HeapObject::FromAddress(new_addr);    copied_to->Iterate(&v);  }#endif  return obj_size;}#ifdef DEBUGvoid MarkCompactCollector::VerifyHeapAfterRelocatingObjects() {  ASSERT(state_ == RELOCATE_OBJECTS);  Heap::new_space()->Verify();  PagedSpaces spaces;  while (PagedSpace* space = spaces.next()) {    space->Verify();    PageIterator it(space, PageIterator::PAGES_IN_USE);    while (it.has_next()) {      Page* p = it.next();      ASSERT_PAGE_OFFSET(p->Offset(p->AllocationTop()));    }  }}#endif#ifdef DEBUGvoid MarkCompactCollector::VerifyCopyingObjects(Object** p) {  if (!(*p)->IsHeapObject()) return;  ASSERT(!Heap::InToSpace(*p));}#endif  // DEBUG// -----------------------------------------------------------------------------// Phase 5: rebuild remembered setsvoid MarkCompactCollector::RebuildRSets() {#ifdef DEBUG  ASSERT(state_ == RELOCATE_OBJECTS);  state_ = REBUILD_RSETS;#endif  Heap::RebuildRSets();}} }  // namespace v8::internal

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -