| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 967 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 current_page_->set_scan_on_scavenge(true); | 978 current_page_->set_scan_on_scavenge(true); |
| 979 ASSERT(start_of_current_page_ != store_buffer_->Top()); | 979 ASSERT(start_of_current_page_ != store_buffer_->Top()); |
| 980 store_buffer_->SetTop(start_of_current_page_); | 980 store_buffer_->SetTop(start_of_current_page_); |
| 981 } | 981 } |
| 982 } else { | 982 } else { |
| 983 UNREACHABLE(); | 983 UNREACHABLE(); |
| 984 } | 984 } |
| 985 } | 985 } |
| 986 | 986 |
| 987 | 987 |
| 988 void PromotionQueue::SetNewLimit(Address limit) { |
| 989 if (emergency_stack_ != NULL) return; |
| 990 |
| 991 limit_ = reinterpret_cast<intptr_t*>(limit); |
| 992 |
| 993 Page* queue_page = Page::FromAllocationTop(reinterpret_cast<Address>(rear_)); |
| 994 Page* limit_page = Page::FromAllocationTop(limit); |
| 995 |
| 996 if (queue_page != limit_page || limit_ <= rear_) { |
| 997 return; |
| 998 } |
| 999 |
| 1000 RelocateQueueHead(); |
| 1001 } |
| 1002 |
| 1003 |
| 1004 void PromotionQueue::RelocateQueueHead() { |
| 1005 ASSERT(emergency_stack_ == NULL); |
| 1006 |
| 1007 Page* p = Page::FromAllocationTop(reinterpret_cast<Address>(rear_)); |
| 1008 intptr_t* head_start = rear_; |
| 1009 intptr_t* head_end = |
| 1010 Min(front_, reinterpret_cast<intptr_t*>(p->body_limit())); |
| 1011 |
| 1012 int entries_count = (head_end - head_start) / kEntrySizeInWords; |
| 1013 |
| 1014 emergency_stack_ = new List<Entry>(2 * entries_count); |
| 1015 |
| 1016 while (head_start != head_end) { |
| 1017 int size = *(head_start++); |
| 1018 HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++)); |
| 1019 emergency_stack_->Add(Entry(obj, size)); |
| 1020 } |
| 1021 rear_ = head_end; |
| 1022 |
| 1023 ASSERT(emergency_stack_->length() > 0); |
| 1024 } |
| 1025 |
| 1026 |
| 988 void Heap::Scavenge() { | 1027 void Heap::Scavenge() { |
| 989 #ifdef DEBUG | 1028 #ifdef DEBUG |
| 990 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); | 1029 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); |
| 991 #endif | 1030 #endif |
| 992 | 1031 |
| 993 gc_state_ = SCAVENGE; | 1032 gc_state_ = SCAVENGE; |
| 994 | 1033 |
| 995 // Implements Cheney's copying algorithm | 1034 // Implements Cheney's copying algorithm |
| 996 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1035 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
| 997 | 1036 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1026 // We treat the top of the to space as a queue of addresses of | 1065 // We treat the top of the to space as a queue of addresses of |
| 1027 // promoted objects. The addresses of newly promoted and unswept | 1066 // promoted objects. The addresses of newly promoted and unswept |
| 1028 // objects lie between a 'front' mark and a 'rear' mark that is | 1067 // objects lie between a 'front' mark and a 'rear' mark that is |
| 1029 // updated as a side effect of promoting an object. | 1068 // updated as a side effect of promoting an object. |
| 1030 // | 1069 // |
| 1031 // There is guaranteed to be enough room at the top of the to space | 1070 // There is guaranteed to be enough room at the top of the to space |
| 1032 // for the addresses of promoted objects: every object promoted | 1071 // for the addresses of promoted objects: every object promoted |
| 1033 // frees up its size in bytes from the top of the new space, and | 1072 // frees up its size in bytes from the top of the new space, and |
| 1034 // objects are at least one pointer in size. | 1073 // objects are at least one pointer in size. |
| 1035 Address new_space_front = new_space_.ToSpaceStart(); | 1074 Address new_space_front = new_space_.ToSpaceStart(); |
| 1036 promotion_queue_.Initialize(new_space_.ToSpaceEnd()); | 1075 promotion_queue_.Initialize(new_space()); |
| 1037 | 1076 |
| 1038 #ifdef DEBUG | 1077 #ifdef DEBUG |
| 1039 store_buffer()->Clean(); | 1078 store_buffer()->Clean(); |
| 1040 #endif | 1079 #endif |
| 1041 | 1080 |
| 1042 ScavengeVisitor scavenge_visitor(this); | 1081 ScavengeVisitor scavenge_visitor(this); |
| 1043 // Copy roots. | 1082 // Copy roots. |
| 1044 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); | 1083 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); |
| 1045 | 1084 |
| 1046 // Copy objects reachable from the old generation. | 1085 // Copy objects reachable from the old generation. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1066 // Scavenge object reachable from the global contexts list directly. | 1105 // Scavenge object reachable from the global contexts list directly. |
| 1067 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); | 1106 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); |
| 1068 | 1107 |
| 1069 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1108 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1070 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( | 1109 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( |
| 1071 &IsUnscavengedHeapObject); | 1110 &IsUnscavengedHeapObject); |
| 1072 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( | 1111 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( |
| 1073 &scavenge_visitor); | 1112 &scavenge_visitor); |
| 1074 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1113 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1075 | 1114 |
| 1076 | |
| 1077 UpdateNewSpaceReferencesInExternalStringTable( | 1115 UpdateNewSpaceReferencesInExternalStringTable( |
| 1078 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1116 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1079 | 1117 |
| 1118 promotion_queue_.Destroy(); |
| 1119 |
| 1080 LiveObjectList::UpdateReferencesForScavengeGC(); | 1120 LiveObjectList::UpdateReferencesForScavengeGC(); |
| 1081 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); | 1121 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
| 1082 incremental_marking()->UpdateMarkingDequeAfterScavenge(); | 1122 incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
| 1083 | 1123 |
| 1084 ASSERT(new_space_front == new_space_.top()); | 1124 ASSERT(new_space_front == new_space_.top()); |
| 1085 | 1125 |
| 1086 // Set age mark. | 1126 // Set age mark. |
| 1087 new_space_.set_age_mark(new_space_.top()); | 1127 new_space_.set_age_mark(new_space_.top()); |
| 1088 | 1128 |
| 1089 new_space_.LowerInlineAllocationLimit( | 1129 new_space_.LowerInlineAllocationLimit( |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 | 1516 |
| 1477 if (object_contents == POINTER_OBJECT) { | 1517 if (object_contents == POINTER_OBJECT) { |
| 1478 heap->promotion_queue()->insert(target, object_size); | 1518 heap->promotion_queue()->insert(target, object_size); |
| 1479 } | 1519 } |
| 1480 | 1520 |
| 1481 heap->tracer()->increment_promoted_objects_size(object_size); | 1521 heap->tracer()->increment_promoted_objects_size(object_size); |
| 1482 return; | 1522 return; |
| 1483 } | 1523 } |
| 1484 } | 1524 } |
| 1485 MaybeObject* allocation = heap->new_space()->AllocateRaw(object_size); | 1525 MaybeObject* allocation = heap->new_space()->AllocateRaw(object_size); |
| 1526 heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); |
| 1486 Object* result = allocation->ToObjectUnchecked(); | 1527 Object* result = allocation->ToObjectUnchecked(); |
| 1487 | 1528 |
| 1488 *slot = MigrateObject(heap, object, HeapObject::cast(result), object_size); | 1529 *slot = MigrateObject(heap, object, HeapObject::cast(result), object_size); |
| 1489 return; | 1530 return; |
| 1490 } | 1531 } |
| 1491 | 1532 |
| 1492 | 1533 |
| 1493 static inline void EvacuateJSFunction(Map* map, | 1534 static inline void EvacuateJSFunction(Map* map, |
| 1494 HeapObject** slot, | 1535 HeapObject** slot, |
| 1495 HeapObject* object) { | 1536 HeapObject* object) { |
| (...skipping 4914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6410 isolate_->heap()->store_buffer()->Compact(); | 6451 isolate_->heap()->store_buffer()->Compact(); |
| 6411 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6452 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6412 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6453 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6413 next = chunk->next_chunk(); | 6454 next = chunk->next_chunk(); |
| 6414 isolate_->memory_allocator()->Free(chunk); | 6455 isolate_->memory_allocator()->Free(chunk); |
| 6415 } | 6456 } |
| 6416 chunks_queued_for_free_ = NULL; | 6457 chunks_queued_for_free_ = NULL; |
| 6417 } | 6458 } |
| 6418 | 6459 |
| 6419 } } // namespace v8::internal | 6460 } } // namespace v8::internal |
| OLD | NEW |