| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) | 79 // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) |
| 80 // Will be 4 * reserved_semispace_size_ to ensure that young | 80 // Will be 4 * reserved_semispace_size_ to ensure that young |
| 81 // generation can be aligned to its size. | 81 // generation can be aligned to its size. |
| 82 survived_since_last_expansion_(0), | 82 survived_since_last_expansion_(0), |
| 83 sweep_generation_(0), | 83 sweep_generation_(0), |
| 84 always_allocate_scope_depth_(0), | 84 always_allocate_scope_depth_(0), |
| 85 linear_allocation_scope_depth_(0), | 85 linear_allocation_scope_depth_(0), |
| 86 contexts_disposed_(0), | 86 contexts_disposed_(0), |
| 87 global_ic_age_(0), | 87 global_ic_age_(0), |
| 88 flush_monomorphic_ics_(false), | 88 flush_monomorphic_ics_(false), |
| 89 allocation_mementos_found_(0), |
| 89 scan_on_scavenge_pages_(0), | 90 scan_on_scavenge_pages_(0), |
| 90 new_space_(this), | 91 new_space_(this), |
| 91 old_pointer_space_(NULL), | 92 old_pointer_space_(NULL), |
| 92 old_data_space_(NULL), | 93 old_data_space_(NULL), |
| 93 code_space_(NULL), | 94 code_space_(NULL), |
| 94 map_space_(NULL), | 95 map_space_(NULL), |
| 95 cell_space_(NULL), | 96 cell_space_(NULL), |
| 96 property_cell_space_(NULL), | 97 property_cell_space_(NULL), |
| 97 lo_space_(NULL), | 98 lo_space_(NULL), |
| 98 gc_state_(NOT_IN_GC), | 99 gc_state_(NOT_IN_GC), |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 marking_(this), | 136 marking_(this), |
| 136 incremental_marking_(this), | 137 incremental_marking_(this), |
| 137 number_idle_notifications_(0), | 138 number_idle_notifications_(0), |
| 138 last_idle_notification_gc_count_(0), | 139 last_idle_notification_gc_count_(0), |
| 139 last_idle_notification_gc_count_init_(false), | 140 last_idle_notification_gc_count_init_(false), |
| 140 mark_sweeps_since_idle_round_started_(0), | 141 mark_sweeps_since_idle_round_started_(0), |
| 141 gc_count_at_last_idle_gc_(0), | 142 gc_count_at_last_idle_gc_(0), |
| 142 scavenges_since_last_idle_round_(kIdleScavengeThreshold), | 143 scavenges_since_last_idle_round_(kIdleScavengeThreshold), |
| 143 gcs_since_last_deopt_(0), | 144 gcs_since_last_deopt_(0), |
| 144 #ifdef VERIFY_HEAP | 145 #ifdef VERIFY_HEAP |
| 145 no_weak_embedded_maps_verification_scope_depth_(0), | 146 no_weak_object_verification_scope_depth_(0), |
| 146 #endif | 147 #endif |
| 147 promotion_queue_(this), | 148 promotion_queue_(this), |
| 148 configured_(false), | 149 configured_(false), |
| 149 chunks_queued_for_free_(NULL), | 150 chunks_queued_for_free_(NULL), |
| 150 relocation_mutex_(NULL) { | 151 relocation_mutex_(NULL) { |
| 151 // Allow build-time customization of the max semispace size. Building | 152 // Allow build-time customization of the max semispace size. Building |
| 152 // V8 with snapshots and a non-default max semispace size is much | 153 // V8 with snapshots and a non-default max semispace size is much |
| 153 // easier if you can define it as part of the build environment. | 154 // easier if you can define it as part of the build environment. |
| 154 #if defined(V8_MAX_SEMISPACE_SIZE) | 155 #if defined(V8_MAX_SEMISPACE_SIZE) |
| 155 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; | 156 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; |
| (...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1321 } | 1322 } |
| 1322 | 1323 |
| 1323 private: | 1324 private: |
| 1324 Heap* heap_; | 1325 Heap* heap_; |
| 1325 }; | 1326 }; |
| 1326 | 1327 |
| 1327 | 1328 |
| 1328 void Heap::Scavenge() { | 1329 void Heap::Scavenge() { |
| 1329 RelocationLock relocation_lock(this); | 1330 RelocationLock relocation_lock(this); |
| 1330 | 1331 |
| 1332 allocation_mementos_found_ = 0; |
| 1333 |
| 1331 #ifdef VERIFY_HEAP | 1334 #ifdef VERIFY_HEAP |
| 1332 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(this); | 1335 if (FLAG_verify_heap) VerifyNonPointerSpacePointers(this); |
| 1333 #endif | 1336 #endif |
| 1334 | 1337 |
| 1335 gc_state_ = SCAVENGE; | 1338 gc_state_ = SCAVENGE; |
| 1336 | 1339 |
| 1337 // Implements Cheney's copying algorithm | 1340 // Implements Cheney's copying algorithm |
| 1338 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1341 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
| 1339 | 1342 |
| 1340 // Clear descriptor cache. | 1343 // Clear descriptor cache. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1468 | 1471 |
| 1469 // Update how much has survived scavenge. | 1472 // Update how much has survived scavenge. |
| 1470 IncrementYoungSurvivorsCounter(static_cast<int>( | 1473 IncrementYoungSurvivorsCounter(static_cast<int>( |
| 1471 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); | 1474 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); |
| 1472 | 1475 |
| 1473 LOG(isolate_, ResourceEvent("scavenge", "end")); | 1476 LOG(isolate_, ResourceEvent("scavenge", "end")); |
| 1474 | 1477 |
| 1475 gc_state_ = NOT_IN_GC; | 1478 gc_state_ = NOT_IN_GC; |
| 1476 | 1479 |
| 1477 scavenges_since_last_idle_round_++; | 1480 scavenges_since_last_idle_round_++; |
| 1481 |
| 1482 if (FLAG_trace_track_allocation_sites && allocation_mementos_found_ > 0) { |
| 1483 PrintF("AllocationMementos found during scavenge = %d\n", |
| 1484 allocation_mementos_found_); |
| 1485 } |
| 1478 } | 1486 } |
| 1479 | 1487 |
| 1480 | 1488 |
| 1481 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, | 1489 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, |
| 1482 Object** p) { | 1490 Object** p) { |
| 1483 MapWord first_word = HeapObject::cast(*p)->map_word(); | 1491 MapWord first_word = HeapObject::cast(*p)->map_word(); |
| 1484 | 1492 |
| 1485 if (!first_word.IsForwardingAddress()) { | 1493 if (!first_word.IsForwardingAddress()) { |
| 1486 // Unreachable external string can be finalized. | 1494 // Unreachable external string can be finalized. |
| 1487 heap->FinalizeExternalString(String::cast(*p)); | 1495 heap->FinalizeExternalString(String::cast(*p)); |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2124 if (alignment != kObjectAlignment) { | 2132 if (alignment != kObjectAlignment) { |
| 2125 ASSERT(alignment == kDoubleAlignment); | 2133 ASSERT(alignment == kDoubleAlignment); |
| 2126 allocation_size += kPointerSize; | 2134 allocation_size += kPointerSize; |
| 2127 } | 2135 } |
| 2128 | 2136 |
| 2129 Heap* heap = map->GetHeap(); | 2137 Heap* heap = map->GetHeap(); |
| 2130 if (heap->ShouldBePromoted(object->address(), object_size)) { | 2138 if (heap->ShouldBePromoted(object->address(), object_size)) { |
| 2131 MaybeObject* maybe_result; | 2139 MaybeObject* maybe_result; |
| 2132 | 2140 |
| 2133 if (object_contents == DATA_OBJECT) { | 2141 if (object_contents == DATA_OBJECT) { |
| 2134 // TODO(mstarzinger): Turn this check into a regular assert soon! | 2142 ASSERT(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE)); |
| 2135 CHECK(heap->AllowedToBeMigrated(object, OLD_DATA_SPACE)); | |
| 2136 maybe_result = heap->old_data_space()->AllocateRaw(allocation_size); | 2143 maybe_result = heap->old_data_space()->AllocateRaw(allocation_size); |
| 2137 } else { | 2144 } else { |
| 2138 // TODO(mstarzinger): Turn this check into a regular assert soon! | 2145 ASSERT(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE)); |
| 2139 CHECK(heap->AllowedToBeMigrated(object, OLD_POINTER_SPACE)); | |
| 2140 maybe_result = heap->old_pointer_space()->AllocateRaw(allocation_size); | 2146 maybe_result = heap->old_pointer_space()->AllocateRaw(allocation_size); |
| 2141 } | 2147 } |
| 2142 | 2148 |
| 2143 Object* result = NULL; // Initialization to please compiler. | 2149 Object* result = NULL; // Initialization to please compiler. |
| 2144 if (maybe_result->ToObject(&result)) { | 2150 if (maybe_result->ToObject(&result)) { |
| 2145 HeapObject* target = HeapObject::cast(result); | 2151 HeapObject* target = HeapObject::cast(result); |
| 2146 | 2152 |
| 2147 if (alignment != kObjectAlignment) { | 2153 if (alignment != kObjectAlignment) { |
| 2148 target = EnsureDoubleAligned(heap, target, allocation_size); | 2154 target = EnsureDoubleAligned(heap, target, allocation_size); |
| 2149 } | 2155 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2160 target, JSFunction::kNonWeakFieldsEndOffset); | 2166 target, JSFunction::kNonWeakFieldsEndOffset); |
| 2161 } else { | 2167 } else { |
| 2162 heap->promotion_queue()->insert(target, object_size); | 2168 heap->promotion_queue()->insert(target, object_size); |
| 2163 } | 2169 } |
| 2164 } | 2170 } |
| 2165 | 2171 |
| 2166 heap->tracer()->increment_promoted_objects_size(object_size); | 2172 heap->tracer()->increment_promoted_objects_size(object_size); |
| 2167 return; | 2173 return; |
| 2168 } | 2174 } |
| 2169 } | 2175 } |
| 2170 // TODO(mstarzinger): Turn this check into a regular assert soon! | 2176 ASSERT(heap->AllowedToBeMigrated(object, NEW_SPACE)); |
| 2171 CHECK(heap->AllowedToBeMigrated(object, NEW_SPACE)); | |
| 2172 MaybeObject* allocation = heap->new_space()->AllocateRaw(allocation_size); | 2177 MaybeObject* allocation = heap->new_space()->AllocateRaw(allocation_size); |
| 2173 heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); | 2178 heap->promotion_queue()->SetNewLimit(heap->new_space()->top()); |
| 2174 Object* result = allocation->ToObjectUnchecked(); | 2179 Object* result = allocation->ToObjectUnchecked(); |
| 2175 HeapObject* target = HeapObject::cast(result); | 2180 HeapObject* target = HeapObject::cast(result); |
| 2176 | 2181 |
| 2177 if (alignment != kObjectAlignment) { | 2182 if (alignment != kObjectAlignment) { |
| 2178 target = EnsureDoubleAligned(heap, target, allocation_size); | 2183 target = EnsureDoubleAligned(heap, target, allocation_size); |
| 2179 } | 2184 } |
| 2180 | 2185 |
| 2181 // Order is important: slot might be inside of the target if target | 2186 // Order is important: slot might be inside of the target if target |
| (...skipping 4541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6723 // Create initial maps. | 6728 // Create initial maps. |
| 6724 if (!CreateInitialMaps()) return false; | 6729 if (!CreateInitialMaps()) return false; |
| 6725 if (!CreateApiObjects()) return false; | 6730 if (!CreateApiObjects()) return false; |
| 6726 | 6731 |
| 6727 // Create initial objects | 6732 // Create initial objects |
| 6728 if (!CreateInitialObjects()) return false; | 6733 if (!CreateInitialObjects()) return false; |
| 6729 | 6734 |
| 6730 native_contexts_list_ = undefined_value(); | 6735 native_contexts_list_ = undefined_value(); |
| 6731 array_buffers_list_ = undefined_value(); | 6736 array_buffers_list_ = undefined_value(); |
| 6732 allocation_sites_list_ = undefined_value(); | 6737 allocation_sites_list_ = undefined_value(); |
| 6738 weak_object_to_code_table_ = undefined_value(); |
| 6733 return true; | 6739 return true; |
| 6734 } | 6740 } |
| 6735 | 6741 |
| 6736 | 6742 |
| 6737 void Heap::SetStackLimits() { | 6743 void Heap::SetStackLimits() { |
| 6738 ASSERT(isolate_ != NULL); | 6744 ASSERT(isolate_ != NULL); |
| 6739 ASSERT(isolate_ == isolate()); | 6745 ASSERT(isolate_ == isolate()); |
| 6740 // On 64 bit machines, pointers are generally out of range of Smis. We write | 6746 // On 64 bit machines, pointers are generally out of range of Smis. We write |
| 6741 // something that looks like an out of range Smi to the GC. | 6747 // something that looks like an out of range Smi to the GC. |
| 6742 | 6748 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6870 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { | 6876 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { |
| 6871 if (gc_epilogue_callbacks_[i].callback == callback) { | 6877 if (gc_epilogue_callbacks_[i].callback == callback) { |
| 6872 gc_epilogue_callbacks_.Remove(i); | 6878 gc_epilogue_callbacks_.Remove(i); |
| 6873 return; | 6879 return; |
| 6874 } | 6880 } |
| 6875 } | 6881 } |
| 6876 UNREACHABLE(); | 6882 UNREACHABLE(); |
| 6877 } | 6883 } |
| 6878 | 6884 |
| 6879 | 6885 |
| 6886 MaybeObject* Heap::AddWeakObjectToCodeDependency(Object* obj, |
| 6887 DependentCode* dep) { |
| 6888 ASSERT(!InNewSpace(obj)); |
| 6889 ASSERT(!InNewSpace(dep)); |
| 6890 MaybeObject* maybe_obj = |
| 6891 WeakHashTable::cast(weak_object_to_code_table_)->Put(obj, dep); |
| 6892 WeakHashTable* table; |
| 6893 if (!maybe_obj->To(&table)) return maybe_obj; |
| 6894 set_weak_object_to_code_table(table); |
| 6895 ASSERT_EQ(dep, WeakHashTable::cast(weak_object_to_code_table_)->Lookup(obj)); |
| 6896 return weak_object_to_code_table_; |
| 6897 } |
| 6898 |
| 6899 |
| 6900 DependentCode* Heap::LookupWeakObjectToCodeDependency(Object* obj) { |
| 6901 Object* dep = WeakHashTable::cast(weak_object_to_code_table_)->Lookup(obj); |
| 6902 if (dep->IsDependentCode()) return DependentCode::cast(dep); |
| 6903 return DependentCode::cast(empty_fixed_array()); |
| 6904 } |
| 6905 |
| 6906 |
| 6907 void Heap::EnsureWeakObjectToCodeTable() { |
| 6908 if (!weak_object_to_code_table()->IsHashTable()) { |
| 6909 set_weak_object_to_code_table(*isolate()->factory()->NewWeakHashTable(16)); |
| 6910 } |
| 6911 } |
| 6912 |
| 6913 |
| 6880 #ifdef DEBUG | 6914 #ifdef DEBUG |
| 6881 | 6915 |
| 6882 class PrintHandleVisitor: public ObjectVisitor { | 6916 class PrintHandleVisitor: public ObjectVisitor { |
| 6883 public: | 6917 public: |
| 6884 void VisitPointers(Object** start, Object** end) { | 6918 void VisitPointers(Object** start, Object** end) { |
| 6885 for (Object** p = start; p < end; p++) | 6919 for (Object** p = start; p < end; p++) |
| 6886 PrintF(" handle %p to %p\n", | 6920 PrintF(" handle %p to %p\n", |
| 6887 reinterpret_cast<void*>(p), | 6921 reinterpret_cast<void*>(p), |
| 6888 reinterpret_cast<void*>(*p)); | 6922 reinterpret_cast<void*>(*p)); |
| 6889 } | 6923 } |
| (...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7870 if (FLAG_concurrent_recompilation) { | 7904 if (FLAG_concurrent_recompilation) { |
| 7871 heap_->relocation_mutex_->Lock(); | 7905 heap_->relocation_mutex_->Lock(); |
| 7872 #ifdef DEBUG | 7906 #ifdef DEBUG |
| 7873 heap_->relocation_mutex_locked_by_optimizer_thread_ = | 7907 heap_->relocation_mutex_locked_by_optimizer_thread_ = |
| 7874 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); | 7908 heap_->isolate()->optimizing_compiler_thread()->IsOptimizerThread(); |
| 7875 #endif // DEBUG | 7909 #endif // DEBUG |
| 7876 } | 7910 } |
| 7877 } | 7911 } |
| 7878 | 7912 |
| 7879 } } // namespace v8::internal | 7913 } } // namespace v8::internal |
| OLD | NEW |