| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 max_alive_after_gc_(0), | 136 max_alive_after_gc_(0), |
| 137 min_in_mutator_(kMaxInt), | 137 min_in_mutator_(kMaxInt), |
| 138 alive_after_last_gc_(0), | 138 alive_after_last_gc_(0), |
| 139 last_gc_end_timestamp_(0.0), | 139 last_gc_end_timestamp_(0.0), |
| 140 store_buffer_(this), | 140 store_buffer_(this), |
| 141 marking_(this), | 141 marking_(this), |
| 142 incremental_marking_(this), | 142 incremental_marking_(this), |
| 143 number_idle_notifications_(0), | 143 number_idle_notifications_(0), |
| 144 last_idle_notification_gc_count_(0), | 144 last_idle_notification_gc_count_(0), |
| 145 last_idle_notification_gc_count_init_(false), | 145 last_idle_notification_gc_count_init_(false), |
| 146 promotion_queue_(this), |
| 146 configured_(false), | 147 configured_(false), |
| 147 chunks_queued_for_free_(NULL) { | 148 chunks_queued_for_free_(NULL) { |
| 148 // Allow build-time customization of the max semispace size. Building | 149 // Allow build-time customization of the max semispace size. Building |
| 149 // V8 with snapshots and a non-default max semispace size is much | 150 // V8 with snapshots and a non-default max semispace size is much |
| 150 // easier if you can define it as part of the build environment. | 151 // easier if you can define it as part of the build environment. |
| 151 #if defined(V8_MAX_SEMISPACE_SIZE) | 152 #if defined(V8_MAX_SEMISPACE_SIZE) |
| 152 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; | 153 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; |
| 153 #endif | 154 #endif |
| 154 | 155 |
| 155 intptr_t max_virtual = OS::MaxVirtualMemory(); | 156 intptr_t max_virtual = OS::MaxVirtualMemory(); |
| (...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 current_page_->set_scan_on_scavenge(true); | 982 current_page_->set_scan_on_scavenge(true); |
| 982 ASSERT(start_of_current_page_ != store_buffer_->Top()); | 983 ASSERT(start_of_current_page_ != store_buffer_->Top()); |
| 983 store_buffer_->SetTop(start_of_current_page_); | 984 store_buffer_->SetTop(start_of_current_page_); |
| 984 } | 985 } |
| 985 } else { | 986 } else { |
| 986 UNREACHABLE(); | 987 UNREACHABLE(); |
| 987 } | 988 } |
| 988 } | 989 } |
| 989 | 990 |
| 990 | 991 |
| 992 void PromotionQueue::Initialize() { |
| 993 // Assumes that a NewSpacePage exactly fits a number of promotion queue |
| 994 // entries (where each is a pair of intptr_t). This allows us to simplify |
| 995 // the test fpr when to switch pages. |
| 996 ASSERT((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) |
| 997 == 0); |
| 998 limit_ = reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceStart()); |
| 999 front_ = rear_ = |
| 1000 reinterpret_cast<intptr_t*>(heap_->new_space()->ToSpaceEnd()); |
| 1001 emergency_stack_ = NULL; |
| 1002 guard_ = false; |
| 1003 } |
| 1004 |
| 1005 |
| 1006 void PromotionQueue::RelocateQueueHead() { |
| 1007 ASSERT(emergency_stack_ == NULL); |
| 1008 |
| 1009 Page* p = Page::FromAllocationTop(reinterpret_cast<Address>(rear_)); |
| 1010 intptr_t* head_start = rear_; |
| 1011 intptr_t* head_end = |
| 1012 Min(front_, reinterpret_cast<intptr_t*>(p->body_limit())); |
| 1013 |
| 1014 int entries_count = (head_end - head_start) / kEntrySizeInWords; |
| 1015 |
| 1016 emergency_stack_ = new List<Entry>(2 * entries_count); |
| 1017 |
| 1018 while (head_start != head_end) { |
| 1019 int size = *(head_start++); |
| 1020 HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++)); |
| 1021 emergency_stack_->Add(Entry(obj, size)); |
| 1022 } |
| 1023 rear_ = head_end; |
| 1024 } |
| 1025 |
| 1026 |
| 991 void Heap::Scavenge() { | 1027 void Heap::Scavenge() { |
| 992 #ifdef DEBUG | 1028 #ifdef DEBUG |
| 993 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); | 1029 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(); |
| 994 #endif | 1030 #endif |
| 995 | 1031 |
| 996 gc_state_ = SCAVENGE; | 1032 gc_state_ = SCAVENGE; |
| 997 | 1033 |
| 998 // Implements Cheney's copying algorithm | 1034 // Implements Cheney's copying algorithm |
| 999 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1035 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
| 1000 | 1036 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1029 // 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 |
| 1030 // promoted objects. The addresses of newly promoted and unswept | 1066 // promoted objects. The addresses of newly promoted and unswept |
| 1031 // 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 |
| 1032 // updated as a side effect of promoting an object. | 1068 // updated as a side effect of promoting an object. |
| 1033 // | 1069 // |
| 1034 // 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 |
| 1035 // for the addresses of promoted objects: every object promoted | 1071 // for the addresses of promoted objects: every object promoted |
| 1036 // 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 |
| 1037 // objects are at least one pointer in size. | 1073 // objects are at least one pointer in size. |
| 1038 Address new_space_front = new_space_.ToSpaceStart(); | 1074 Address new_space_front = new_space_.ToSpaceStart(); |
| 1039 promotion_queue_.Initialize(new_space_.ToSpaceEnd()); | 1075 promotion_queue_.Initialize(); |
| 1040 | 1076 |
| 1041 #ifdef DEBUG | 1077 #ifdef DEBUG |
| 1042 store_buffer()->Clean(); | 1078 store_buffer()->Clean(); |
| 1043 #endif | 1079 #endif |
| 1044 | 1080 |
| 1045 ScavengeVisitor scavenge_visitor(this); | 1081 ScavengeVisitor scavenge_visitor(this); |
| 1046 // Copy roots. | 1082 // Copy roots. |
| 1047 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); | 1083 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); |
| 1048 | 1084 |
| 1049 // Copy objects reachable from the old generation. | 1085 // Copy objects reachable from the old generation. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1069 // Scavenge object reachable from the global contexts list directly. | 1105 // Scavenge object reachable from the global contexts list directly. |
| 1070 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); | 1106 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); |
| 1071 | 1107 |
| 1072 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1108 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1073 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( | 1109 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( |
| 1074 &IsUnscavengedHeapObject); | 1110 &IsUnscavengedHeapObject); |
| 1075 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( | 1111 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( |
| 1076 &scavenge_visitor); | 1112 &scavenge_visitor); |
| 1077 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1113 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1078 | 1114 |
| 1079 | |
| 1080 UpdateNewSpaceReferencesInExternalStringTable( | 1115 UpdateNewSpaceReferencesInExternalStringTable( |
| 1081 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1116 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1082 | 1117 |
| 1118 promotion_queue_.Destroy(); |
| 1119 |
| 1083 LiveObjectList::UpdateReferencesForScavengeGC(); | 1120 LiveObjectList::UpdateReferencesForScavengeGC(); |
| 1084 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); | 1121 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
| 1085 incremental_marking()->UpdateMarkingDequeAfterScavenge(); | 1122 incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
| 1086 | 1123 |
| 1087 ASSERT(new_space_front == new_space_.top()); | 1124 ASSERT(new_space_front == new_space_.top()); |
| 1088 | 1125 |
| 1089 // Set age mark. | 1126 // Set age mark. |
| 1090 new_space_.set_age_mark(new_space_.top()); | 1127 new_space_.set_age_mark(new_space_.top()); |
| 1091 | 1128 |
| 1092 new_space_.LowerInlineAllocationLimit( | 1129 new_space_.LowerInlineAllocationLimit( |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 | 1516 |
| 1480 if (object_contents == POINTER_OBJECT) { | 1517 if (object_contents == POINTER_OBJECT) { |
| 1481 heap->promotion_queue()->insert(target, object_size); | 1518 heap->promotion_queue()->insert(target, object_size); |
| 1482 } | 1519 } |
| 1483 | 1520 |
| 1484 heap->tracer()->increment_promoted_objects_size(object_size); | 1521 heap->tracer()->increment_promoted_objects_size(object_size); |
| 1485 return; | 1522 return; |
| 1486 } | 1523 } |
| 1487 } | 1524 } |
| 1488 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()); |
| 1489 Object* result = allocation->ToObjectUnchecked(); | 1527 Object* result = allocation->ToObjectUnchecked(); |
| 1490 | 1528 |
| 1491 *slot = MigrateObject(heap, object, HeapObject::cast(result), object_size); | 1529 *slot = MigrateObject(heap, object, HeapObject::cast(result), object_size); |
| 1492 return; | 1530 return; |
| 1493 } | 1531 } |
| 1494 | 1532 |
| 1495 | 1533 |
| 1496 static inline void EvacuateJSFunction(Map* map, | 1534 static inline void EvacuateJSFunction(Map* map, |
| 1497 HeapObject** slot, | 1535 HeapObject** slot, |
| 1498 HeapObject* object) { | 1536 HeapObject* object) { |
| (...skipping 4914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6413 isolate_->heap()->store_buffer()->Compact(); | 6451 isolate_->heap()->store_buffer()->Compact(); |
| 6414 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6452 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6415 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6453 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6416 next = chunk->next_chunk(); | 6454 next = chunk->next_chunk(); |
| 6417 isolate_->memory_allocator()->Free(chunk); | 6455 isolate_->memory_allocator()->Free(chunk); |
| 6418 } | 6456 } |
| 6419 chunks_queued_for_free_ = NULL; | 6457 chunks_queued_for_free_ = NULL; |
| 6420 } | 6458 } |
| 6421 | 6459 |
| 6422 } } // namespace v8::internal | 6460 } } // namespace v8::internal |
| OLD | NEW |