Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 set_native_contexts_list(NULL); | 159 set_native_contexts_list(NULL); |
| 160 set_array_buffers_list(Smi::FromInt(0)); | 160 set_array_buffers_list(Smi::FromInt(0)); |
| 161 set_allocation_sites_list(Smi::FromInt(0)); | 161 set_allocation_sites_list(Smi::FromInt(0)); |
| 162 set_encountered_weak_collections(Smi::FromInt(0)); | 162 set_encountered_weak_collections(Smi::FromInt(0)); |
| 163 set_encountered_weak_cells(Smi::FromInt(0)); | 163 set_encountered_weak_cells(Smi::FromInt(0)); |
| 164 // Put a dummy entry in the remembered pages so we can find the list the | 164 // Put a dummy entry in the remembered pages so we can find the list the |
| 165 // minidump even if there are no real unmapped pages. | 165 // minidump even if there are no real unmapped pages. |
| 166 RememberUnmappedPage(NULL, false); | 166 RememberUnmappedPage(NULL, false); |
| 167 | 167 |
| 168 ClearObjectStats(true); | 168 ClearObjectStats(true); |
| 169 | |
| 170 #ifdef TRACE_RETAINING_PATH | |
| 171 ClearRetainingInfo(); | |
| 172 #endif | |
| 169 } | 173 } |
| 170 | 174 |
| 171 | 175 |
| 172 intptr_t Heap::Capacity() { | 176 intptr_t Heap::Capacity() { |
| 173 if (!HasBeenSetUp()) return 0; | 177 if (!HasBeenSetUp()) return 0; |
| 174 | 178 |
| 175 return new_space_.Capacity() + old_pointer_space_->Capacity() + | 179 return new_space_.Capacity() + old_pointer_space_->Capacity() + |
| 176 old_data_space_->Capacity() + code_space_->Capacity() + | 180 old_data_space_->Capacity() + code_space_->Capacity() + |
| 177 map_space_->Capacity() + cell_space_->Capacity() + | 181 map_space_->Capacity() + cell_space_->Capacity() + |
| 178 property_cell_space_->Capacity(); | 182 property_cell_space_->Capacity(); |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 607 | 611 |
| 608 // Process pretenuring feedback and update allocation sites. | 612 // Process pretenuring feedback and update allocation sites. |
| 609 ProcessPretenuringFeedback(); | 613 ProcessPretenuringFeedback(); |
| 610 | 614 |
| 611 #ifdef VERIFY_HEAP | 615 #ifdef VERIFY_HEAP |
| 612 if (FLAG_verify_heap) { | 616 if (FLAG_verify_heap) { |
| 613 Verify(); | 617 Verify(); |
| 614 } | 618 } |
| 615 #endif | 619 #endif |
| 616 | 620 |
| 621 #ifdef TRACE_RETAINING_PATH | |
| 622 ClearRetainingInfo(); | |
| 623 #endif | |
| 624 | |
| 617 AllowHeapAllocation for_the_rest_of_the_epilogue; | 625 AllowHeapAllocation for_the_rest_of_the_epilogue; |
| 618 | 626 |
| 619 #ifdef DEBUG | 627 #ifdef DEBUG |
| 620 if (FLAG_print_global_handles) isolate_->global_handles()->Print(); | 628 if (FLAG_print_global_handles) isolate_->global_handles()->Print(); |
| 621 if (FLAG_print_handles) PrintHandles(); | 629 if (FLAG_print_handles) PrintHandles(); |
| 622 if (FLAG_gc_verbose) Print(); | 630 if (FLAG_gc_verbose) Print(); |
| 623 if (FLAG_code_stats) ReportCodeStatistics("After GC"); | 631 if (FLAG_code_stats) ReportCodeStatistics("After GC"); |
| 624 #endif | 632 #endif |
| 625 if (FLAG_deopt_every_n_garbage_collections > 0) { | 633 if (FLAG_deopt_every_n_garbage_collections > 0) { |
| 626 // TODO(jkummerow/ulan/jarin): This is not safe! We can't assume that | 634 // TODO(jkummerow/ulan/jarin): This is not safe! We can't assume that |
| (...skipping 4410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5037 | 5045 |
| 5038 | 5046 |
| 5039 void Heap::IterateSmiRoots(ObjectVisitor* v) { | 5047 void Heap::IterateSmiRoots(ObjectVisitor* v) { |
| 5040 // Acquire execution access since we are going to read stack limit values. | 5048 // Acquire execution access since we are going to read stack limit values. |
| 5041 ExecutionAccess access(isolate()); | 5049 ExecutionAccess access(isolate()); |
| 5042 v->VisitPointers(&roots_[kSmiRootsStart], &roots_[kRootListLength]); | 5050 v->VisitPointers(&roots_[kSmiRootsStart], &roots_[kRootListLength]); |
| 5043 v->Synchronize(VisitorSynchronization::kSmiRootList); | 5051 v->Synchronize(VisitorSynchronization::kSmiRootList); |
| 5044 } | 5052 } |
| 5045 | 5053 |
| 5046 | 5054 |
| 5055 #ifdef TRACE_RETAINING_PATH | |
| 5056 #define TRACE_ROOT(root) SetCurrentRootRetainer(std::string(root)) | |
| 5057 #else | |
| 5058 #define TRACE_ROOT(root) | |
| 5059 #endif | |
| 5060 | |
| 5061 | |
| 5047 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { | 5062 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { |
| 5063 TRACE_ROOT("[strong root list]"); | |
| 5048 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); | 5064 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); |
| 5049 v->Synchronize(VisitorSynchronization::kStrongRootList); | 5065 v->Synchronize(VisitorSynchronization::kStrongRootList); |
| 5050 | 5066 |
| 5067 TRACE_ROOT("[internalized string]"); | |
| 5051 v->VisitPointer(bit_cast<Object**>(&hidden_string_)); | 5068 v->VisitPointer(bit_cast<Object**>(&hidden_string_)); |
| 5052 v->Synchronize(VisitorSynchronization::kInternalizedString); | 5069 v->Synchronize(VisitorSynchronization::kInternalizedString); |
| 5053 | 5070 |
| 5071 TRACE_ROOT("[bootstrapper]"); | |
| 5054 isolate_->bootstrapper()->Iterate(v); | 5072 isolate_->bootstrapper()->Iterate(v); |
| 5055 v->Synchronize(VisitorSynchronization::kBootstrapper); | 5073 v->Synchronize(VisitorSynchronization::kBootstrapper); |
| 5074 | |
| 5075 TRACE_ROOT("[isolate threads]"); | |
| 5056 isolate_->Iterate(v); | 5076 isolate_->Iterate(v); |
| 5057 v->Synchronize(VisitorSynchronization::kTop); | 5077 v->Synchronize(VisitorSynchronization::kTop); |
| 5078 | |
| 5079 TRACE_ROOT("[isolate relocatable]"); | |
| 5058 Relocatable::Iterate(isolate_, v); | 5080 Relocatable::Iterate(isolate_, v); |
| 5059 v->Synchronize(VisitorSynchronization::kRelocatable); | 5081 v->Synchronize(VisitorSynchronization::kRelocatable); |
| 5060 | 5082 |
| 5083 TRACE_ROOT("[deoptimizer data]"); | |
| 5061 if (isolate_->deoptimizer_data() != NULL) { | 5084 if (isolate_->deoptimizer_data() != NULL) { |
| 5062 isolate_->deoptimizer_data()->Iterate(v); | 5085 isolate_->deoptimizer_data()->Iterate(v); |
| 5063 } | 5086 } |
| 5064 v->Synchronize(VisitorSynchronization::kDebug); | 5087 v->Synchronize(VisitorSynchronization::kDebug); |
| 5088 | |
| 5089 TRACE_ROOT("[compilation cache]"); | |
| 5065 isolate_->compilation_cache()->Iterate(v); | 5090 isolate_->compilation_cache()->Iterate(v); |
| 5066 v->Synchronize(VisitorSynchronization::kCompilationCache); | 5091 v->Synchronize(VisitorSynchronization::kCompilationCache); |
| 5067 | 5092 |
| 5068 // Iterate over local handles in handle scopes. | 5093 // Iterate over local handles in handle scopes. |
| 5094 TRACE_ROOT("[internal handles]"); | |
| 5069 isolate_->handle_scope_implementer()->Iterate(v); | 5095 isolate_->handle_scope_implementer()->Iterate(v); |
| 5096 TRACE_ROOT("[internal deferred handles]"); | |
| 5070 isolate_->IterateDeferredHandles(v); | 5097 isolate_->IterateDeferredHandles(v); |
| 5071 v->Synchronize(VisitorSynchronization::kHandleScope); | 5098 v->Synchronize(VisitorSynchronization::kHandleScope); |
| 5072 | 5099 |
| 5073 // Iterate over the builtin code objects and code stubs in the | 5100 // Iterate over the builtin code objects and code stubs in the |
| 5074 // heap. Note that it is not necessary to iterate over code objects | 5101 // heap. Note that it is not necessary to iterate over code objects |
| 5075 // on scavenge collections. | 5102 // on scavenge collections. |
| 5103 TRACE_ROOT("[builtins]"); | |
| 5076 if (mode != VISIT_ALL_IN_SCAVENGE) { | 5104 if (mode != VISIT_ALL_IN_SCAVENGE) { |
| 5077 isolate_->builtins()->IterateBuiltins(v); | 5105 isolate_->builtins()->IterateBuiltins(v); |
| 5078 } | 5106 } |
| 5079 v->Synchronize(VisitorSynchronization::kBuiltins); | 5107 v->Synchronize(VisitorSynchronization::kBuiltins); |
| 5080 | 5108 |
| 5081 // Iterate over global handles. | 5109 // Iterate over global handles. |
| 5110 TRACE_ROOT("[global handles]"); | |
| 5082 switch (mode) { | 5111 switch (mode) { |
| 5083 case VISIT_ONLY_STRONG: | 5112 case VISIT_ONLY_STRONG: |
| 5084 isolate_->global_handles()->IterateStrongRoots(v); | 5113 isolate_->global_handles()->IterateStrongRoots(v); |
| 5085 break; | 5114 break; |
| 5086 case VISIT_ALL_IN_SCAVENGE: | 5115 case VISIT_ALL_IN_SCAVENGE: |
| 5087 isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v); | 5116 isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v); |
| 5088 break; | 5117 break; |
| 5089 case VISIT_ALL_IN_SWEEP_NEWSPACE: | 5118 case VISIT_ALL_IN_SWEEP_NEWSPACE: |
| 5090 case VISIT_ALL: | 5119 case VISIT_ALL: |
| 5091 isolate_->global_handles()->IterateAllRoots(v); | 5120 isolate_->global_handles()->IterateAllRoots(v); |
| 5092 break; | 5121 break; |
| 5093 } | 5122 } |
| 5094 v->Synchronize(VisitorSynchronization::kGlobalHandles); | 5123 v->Synchronize(VisitorSynchronization::kGlobalHandles); |
| 5095 | 5124 |
| 5096 // Iterate over eternal handles. | 5125 // Iterate over eternal handles. |
| 5126 TRACE_ROOT("[eternal handles]"); | |
| 5097 if (mode == VISIT_ALL_IN_SCAVENGE) { | 5127 if (mode == VISIT_ALL_IN_SCAVENGE) { |
| 5098 isolate_->eternal_handles()->IterateNewSpaceRoots(v); | 5128 isolate_->eternal_handles()->IterateNewSpaceRoots(v); |
| 5099 } else { | 5129 } else { |
| 5100 isolate_->eternal_handles()->IterateAllRoots(v); | 5130 isolate_->eternal_handles()->IterateAllRoots(v); |
| 5101 } | 5131 } |
| 5102 v->Synchronize(VisitorSynchronization::kEternalHandles); | 5132 v->Synchronize(VisitorSynchronization::kEternalHandles); |
| 5103 | 5133 |
| 5134 TRACE_ROOT("[isolate inactive threads]"); | |
| 5104 // Iterate over pointers being held by inactive threads. | 5135 // Iterate over pointers being held by inactive threads. |
| 5105 isolate_->thread_manager()->Iterate(v); | 5136 isolate_->thread_manager()->Iterate(v); |
| 5106 v->Synchronize(VisitorSynchronization::kThreadManager); | 5137 v->Synchronize(VisitorSynchronization::kThreadManager); |
| 5107 | 5138 |
| 5108 // Iterate over the pointers the Serialization/Deserialization code is | 5139 // Iterate over the pointers the Serialization/Deserialization code is |
| 5109 // holding. | 5140 // holding. |
| 5110 // During garbage collection this keeps the partial snapshot cache alive. | 5141 // During garbage collection this keeps the partial snapshot cache alive. |
| 5111 // During deserialization of the startup snapshot this creates the partial | 5142 // During deserialization of the startup snapshot this creates the partial |
| 5112 // snapshot cache and deserializes the objects it refers to. During | 5143 // snapshot cache and deserializes the objects it refers to. During |
| 5113 // serialization this does nothing, since the partial snapshot cache is | 5144 // serialization this does nothing, since the partial snapshot cache is |
| 5114 // empty. However the next thing we do is create the partial snapshot, | 5145 // empty. However the next thing we do is create the partial snapshot, |
| 5115 // filling up the partial snapshot cache with objects it needs as we go. | 5146 // filling up the partial snapshot cache with objects it needs as we go. |
| 5147 TRACE_ROOT("[serializer/deserializer]"); | |
| 5116 SerializerDeserializer::Iterate(isolate_, v); | 5148 SerializerDeserializer::Iterate(isolate_, v); |
| 5117 // We don't do a v->Synchronize call here, because in debug mode that will | 5149 // We don't do a v->Synchronize call here, because in debug mode that will |
| 5118 // output a flag to the snapshot. However at this point the serializer and | 5150 // output a flag to the snapshot. However at this point the serializer and |
| 5119 // deserializer are deliberately a little unsynchronized (see above) so the | 5151 // deserializer are deliberately a little unsynchronized (see above) so the |
| 5120 // checking of the sync flag in the snapshot would fail. | 5152 // checking of the sync flag in the snapshot would fail. |
| 5153 TRACE_ROOT("[]"); | |
| 5121 } | 5154 } |
| 5122 | 5155 |
| 5123 | 5156 |
| 5124 // TODO(1236194): Since the heap size is configurable on the command line | 5157 // TODO(1236194): Since the heap size is configurable on the command line |
| 5125 // and through the API, we should gracefully handle the case that the heap | 5158 // and through the API, we should gracefully handle the case that the heap |
| 5126 // size is not big enough to fit all the initial objects. | 5159 // size is not big enough to fit all the initial objects. |
| 5127 bool Heap::ConfigureHeap(int max_semi_space_size, int max_old_space_size, | 5160 bool Heap::ConfigureHeap(int max_semi_space_size, int max_old_space_size, |
| 5128 int max_executable_size, size_t code_range_size) { | 5161 int max_executable_size, size_t code_range_size) { |
| 5129 if (HasBeenSetUp()) return false; | 5162 if (HasBeenSetUp()) return false; |
| 5130 | 5163 |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5517 roots_[kStackLimitRootIndex] = reinterpret_cast<Object*>( | 5550 roots_[kStackLimitRootIndex] = reinterpret_cast<Object*>( |
| 5518 (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag); | 5551 (isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag); |
| 5519 roots_[kRealStackLimitRootIndex] = reinterpret_cast<Object*>( | 5552 roots_[kRealStackLimitRootIndex] = reinterpret_cast<Object*>( |
| 5520 (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag); | 5553 (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag); |
| 5521 } | 5554 } |
| 5522 | 5555 |
| 5523 | 5556 |
| 5524 void Heap::NotifyDeserializationComplete() { deserialization_complete_ = true; } | 5557 void Heap::NotifyDeserializationComplete() { deserialization_complete_ = true; } |
| 5525 | 5558 |
| 5526 | 5559 |
| 5560 #ifdef TRACE_RETAINING_PATH | |
| 5561 void Heap::SetCurrentRetainer(HeapObject* obj) { current_retainer_ = obj; } | |
| 5562 | |
| 5563 | |
| 5564 void Heap::SetCurrentRootRetainer(std::string root) { | |
| 5565 current_root_retainer_ = root; | |
| 5566 } | |
| 5567 | |
| 5568 | |
| 5569 void Heap::PrintRetainingPath(HeapObject* obj, const char* comment) { | |
| 5570 PrintF("Retaining path for %s [%p]:\n", comment, static_cast<void*>(obj)); | |
| 5571 obj->ShortPrint(); | |
| 5572 PrintF("\n"); | |
| 5573 while (retainer_.count(obj) && retainer_[obj] != NULL) { | |
| 5574 PrintF("^^^^^^^^\n"); | |
| 5575 obj = retainer_[obj]; | |
| 5576 #ifdef OBJECT_PRINT | |
| 5577 obj->Print(); | |
| 5578 #else | |
| 5579 obj->ShortPrint(); | |
| 5580 #endif | |
| 5581 PrintF("\n"); | |
| 5582 } | |
| 5583 if (root_retainer_.count(obj)) { | |
| 5584 PrintF("^^^^^^^^\n"); | |
| 5585 PrintF("%s\n", root_retainer_[obj].c_str()); | |
| 5586 } | |
| 5587 PrintF("End of retaining path.\n"); | |
| 5588 } | |
| 5589 | |
| 5590 | |
| 5591 void Heap::AddRetainedObject(HeapObject* obj) { | |
| 5592 if (retainer_.count(obj)) return; | |
| 5593 retainer_[obj] = current_retainer_; | |
| 5594 if (current_retainer_ == NULL) { | |
| 5595 root_retainer_[obj] = current_root_retainer_; | |
| 5596 } | |
| 5597 const char* filter = FLAG_trace_retaining_path_for; | |
| 5598 if (obj->IsJSObject() && *filter != 0) { | |
| 5599 JSObject* jsobj = JSObject::cast(obj); | |
| 5600 String* name = jsobj->constructor_name(); | |
| 5601 if (!strcmp(filter, name->ToCString().get())) { | |
| 5602 PrintRetainingPath(obj, filter); | |
| 5603 } | |
| 5604 } | |
| 5605 if (FLAG_track_detached_contexts && obj->IsNativeContext()) { | |
| 5606 FixedArray* dc = detached_contexts(); | |
| 5607 int length = dc->length(); | |
| 5608 for (int i = 0; i < length; i += 2) { | |
| 5609 int mark_sweeps = Smi::cast(dc->get(i))->value(); | |
| 5610 if (mark_sweeps > 5 && WeakCell::cast(dc->get(i + 1))->value() == obj) { | |
|
Hannes Payer (out of office)
2015/02/06 13:31:31
make 5 a constant
| |
| 5611 PrintRetainingPath(obj, "detached context"); | |
| 5612 } | |
| 5613 } | |
| 5614 } | |
| 5615 } | |
| 5616 | |
| 5617 | |
| 5618 void Heap::ClearRetainingInfo() { | |
| 5619 retainer_.clear(); | |
| 5620 root_retainer_.clear(); | |
| 5621 current_retainer_ = NULL; | |
| 5622 current_root_retainer_ = ""; | |
| 5623 } | |
| 5624 #endif | |
| 5625 | |
|
Hannes Payer (out of office)
2015/02/06 13:31:32
+1 newline
| |
| 5527 void Heap::TearDown() { | 5626 void Heap::TearDown() { |
| 5528 #ifdef VERIFY_HEAP | 5627 #ifdef VERIFY_HEAP |
| 5529 if (FLAG_verify_heap) { | 5628 if (FLAG_verify_heap) { |
| 5530 Verify(); | 5629 Verify(); |
| 5531 } | 5630 } |
| 5532 #endif | 5631 #endif |
| 5533 | 5632 |
| 5534 UpdateMaximumCommitted(); | 5633 UpdateMaximumCommitted(); |
| 5535 | 5634 |
| 5536 if (FLAG_print_cumulative_gc_stat) { | 5635 if (FLAG_print_cumulative_gc_stat) { |
| (...skipping 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6488 static_cast<int>(object_sizes_last_time_[index])); | 6587 static_cast<int>(object_sizes_last_time_[index])); |
| 6489 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 6588 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 6490 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 6589 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 6491 | 6590 |
| 6492 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 6591 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 6493 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 6592 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 6494 ClearObjectStats(); | 6593 ClearObjectStats(); |
| 6495 } | 6594 } |
| 6496 } | 6595 } |
| 6497 } // namespace v8::internal | 6596 } // namespace v8::internal |
| OLD | NEW |