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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 contexts_disposed_(0), | 100 contexts_disposed_(0), |
101 scan_on_scavenge_pages_(0), | 101 scan_on_scavenge_pages_(0), |
102 new_space_(this), | 102 new_space_(this), |
103 old_pointer_space_(NULL), | 103 old_pointer_space_(NULL), |
104 old_data_space_(NULL), | 104 old_data_space_(NULL), |
105 code_space_(NULL), | 105 code_space_(NULL), |
106 map_space_(NULL), | 106 map_space_(NULL), |
107 cell_space_(NULL), | 107 cell_space_(NULL), |
108 lo_space_(NULL), | 108 lo_space_(NULL), |
109 gc_state_(NOT_IN_GC), | 109 gc_state_(NOT_IN_GC), |
110 mc_count_(0), | |
111 ms_count_(0), | 110 ms_count_(0), |
112 gc_count_(0), | 111 gc_count_(0), |
113 unflattened_strings_length_(0), | 112 unflattened_strings_length_(0), |
114 #ifdef DEBUG | 113 #ifdef DEBUG |
115 allocation_allowed_(true), | 114 allocation_allowed_(true), |
116 allocation_timeout_(0), | 115 allocation_timeout_(0), |
117 disallow_allocation_failure_(false), | 116 disallow_allocation_failure_(false), |
118 debug_utils_(NULL), | 117 debug_utils_(NULL), |
119 #endif // DEBUG | 118 #endif // DEBUG |
120 old_gen_promotion_limit_(kMinimumPromotionLimit), | 119 old_gen_promotion_limit_(kMinimumPromotionLimit), |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
767 | 766 |
768 // Update relocatables. | 767 // Update relocatables. |
769 Relocatable::PostGarbageCollectionProcessing(); | 768 Relocatable::PostGarbageCollectionProcessing(); |
770 | 769 |
771 if (collector == MARK_COMPACTOR) { | 770 if (collector == MARK_COMPACTOR) { |
772 // Register the amount of external allocated memory. | 771 // Register the amount of external allocated memory. |
773 amount_of_external_allocated_memory_at_last_global_gc_ = | 772 amount_of_external_allocated_memory_at_last_global_gc_ = |
774 amount_of_external_allocated_memory_; | 773 amount_of_external_allocated_memory_; |
775 } | 774 } |
776 | 775 |
777 GCCallbackFlags callback_flags = tracer->is_compacting() | 776 GCCallbackFlags callback_flags = kNoGCCallbackFlags; |
778 ? kGCCallbackFlagCompacted | |
779 : kNoGCCallbackFlags; | |
780 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { | 777 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { |
781 if (gc_type & gc_epilogue_callbacks_[i].gc_type) { | 778 if (gc_type & gc_epilogue_callbacks_[i].gc_type) { |
782 gc_epilogue_callbacks_[i].callback(gc_type, callback_flags); | 779 gc_epilogue_callbacks_[i].callback(gc_type, callback_flags); |
783 } | 780 } |
784 } | 781 } |
785 | 782 |
786 if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) { | 783 if (collector == MARK_COMPACTOR && global_gc_epilogue_callback_) { |
787 ASSERT(!allocation_allowed_); | 784 ASSERT(!allocation_allowed_); |
788 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 785 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
789 global_gc_epilogue_callback_(); | 786 global_gc_epilogue_callback_(); |
790 } | 787 } |
791 VerifySymbolTable(); | 788 VerifySymbolTable(); |
792 | 789 |
793 return next_gc_likely_to_collect_more; | 790 return next_gc_likely_to_collect_more; |
794 } | 791 } |
795 | 792 |
796 | 793 |
797 void Heap::MarkCompact(GCTracer* tracer) { | 794 void Heap::MarkCompact(GCTracer* tracer) { |
798 gc_state_ = MARK_COMPACT; | 795 gc_state_ = MARK_COMPACT; |
799 LOG(isolate_, ResourceEvent("markcompact", "begin")); | 796 LOG(isolate_, ResourceEvent("markcompact", "begin")); |
800 | 797 |
801 mark_compact_collector_.Prepare(tracer); | 798 mark_compact_collector_.Prepare(tracer); |
802 | 799 |
803 bool is_compacting = mark_compact_collector_.IsCompacting(); | 800 ms_count_++; |
801 tracer->set_full_gc_count(ms_count_); | |
804 | 802 |
805 if (is_compacting) { | 803 MarkCompactPrologue(); |
806 mc_count_++; | |
807 } else { | |
808 ms_count_++; | |
809 } | |
810 tracer->set_full_gc_count(mc_count_ + ms_count_); | |
811 | |
812 MarkCompactPrologue(is_compacting); | |
813 | 804 |
814 mark_compact_collector_.CollectGarbage(); | 805 mark_compact_collector_.CollectGarbage(); |
815 | 806 |
816 LOG(isolate_, ResourceEvent("markcompact", "end")); | 807 LOG(isolate_, ResourceEvent("markcompact", "end")); |
817 | 808 |
818 gc_state_ = NOT_IN_GC; | 809 gc_state_ = NOT_IN_GC; |
819 | 810 |
820 Shrink(); | 811 Shrink(); |
821 | 812 |
822 isolate_->counters()->objs_since_last_full()->Set(0); | 813 isolate_->counters()->objs_since_last_full()->Set(0); |
823 | 814 |
824 contexts_disposed_ = 0; | 815 contexts_disposed_ = 0; |
825 } | 816 } |
826 | 817 |
827 | 818 |
828 void Heap::MarkCompactPrologue(bool is_compacting) { | 819 void Heap::MarkCompactPrologue() { |
829 // At any old GC clear the keyed lookup cache to enable collection of unused | 820 // At any old GC clear the keyed lookup cache to enable collection of unused |
830 // maps. | 821 // maps. |
831 isolate_->keyed_lookup_cache()->Clear(); | 822 isolate_->keyed_lookup_cache()->Clear(); |
832 isolate_->context_slot_cache()->Clear(); | 823 isolate_->context_slot_cache()->Clear(); |
833 isolate_->descriptor_lookup_cache()->Clear(); | 824 isolate_->descriptor_lookup_cache()->Clear(); |
834 | 825 |
835 isolate_->compilation_cache()->MarkCompactPrologue(); | 826 isolate_->compilation_cache()->MarkCompactPrologue(); |
836 | 827 |
837 CompletelyClearInstanceofCache(); | 828 CompletelyClearInstanceofCache(); |
838 | 829 |
839 if (is_compacting) FlushNumberStringCache(); | 830 // TODO(gc) select heuristic for flushing NumberString cache with |
831 // FlushNumberStringCache | |
840 | 832 |
841 ClearNormalizedMapCaches(); | 833 ClearNormalizedMapCaches(); |
842 } | 834 } |
843 | 835 |
844 | 836 |
845 Object* Heap::FindCodeObject(Address a) { | 837 Object* Heap::FindCodeObject(Address a) { |
846 Object* obj = NULL; // Initialization to please compiler. | 838 Object* obj = NULL; // Initialization to please compiler. |
847 { MaybeObject* maybe_obj = code_space_->FindObject(a); | 839 { MaybeObject* maybe_obj = code_space_->FindObject(a); |
848 if (!maybe_obj->ToObject(&obj)) { | 840 if (!maybe_obj->ToObject(&obj)) { |
849 obj = lo_space_->FindObject(a)->ToObjectUnchecked(); | 841 obj = lo_space_->FindObject(a)->ToObjectUnchecked(); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1044 | 1036 |
1045 ScavengeVisitor scavenge_visitor(this); | 1037 ScavengeVisitor scavenge_visitor(this); |
1046 // Copy roots. | 1038 // Copy roots. |
1047 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); | 1039 IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE); |
1048 | 1040 |
1049 // Copy objects reachable from the old generation. | 1041 // Copy objects reachable from the old generation. |
1050 { | 1042 { |
1051 StoreBufferRebuildScope scope(this, | 1043 StoreBufferRebuildScope scope(this, |
1052 store_buffer(), | 1044 store_buffer(), |
1053 &ScavengeStoreBufferCallback); | 1045 &ScavengeStoreBufferCallback); |
1054 store_buffer()->IteratePointersToNewSpace(&ScavengeObject); | 1046 store_buffer()->IteratePointersToNewSpace(&ScavengeObject, |
1047 StoreBuffer::VISIT_ALL_SLOTS); | |
1055 } | 1048 } |
1056 | 1049 |
1057 // Copy objects reachable from cells by scavenging cell values directly. | 1050 // Copy objects reachable from cells by scavenging cell values directly. |
1058 HeapObjectIterator cell_iterator(cell_space_); | 1051 HeapObjectIterator cell_iterator(cell_space_); |
1059 for (HeapObject* cell = cell_iterator.Next(); | 1052 for (HeapObject* cell = cell_iterator.Next(); |
1060 cell != NULL; cell = cell_iterator.Next()) { | 1053 cell != NULL; cell = cell_iterator.Next()) { |
1061 if (cell->IsJSGlobalPropertyCell()) { | 1054 if (cell->IsJSGlobalPropertyCell()) { |
1062 Address value_address = | 1055 Address value_address = |
1063 reinterpret_cast<Address>(cell) + | 1056 reinterpret_cast<Address>(cell) + |
1064 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); | 1057 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1142 // String got promoted. Move it to the old string list. | 1135 // String got promoted. Move it to the old string list. |
1143 external_string_table_.AddOldString(target); | 1136 external_string_table_.AddOldString(target); |
1144 } | 1137 } |
1145 } | 1138 } |
1146 | 1139 |
1147 ASSERT(last <= end); | 1140 ASSERT(last <= end); |
1148 external_string_table_.ShrinkNewStrings(static_cast<int>(last - start)); | 1141 external_string_table_.ShrinkNewStrings(static_cast<int>(last - start)); |
1149 } | 1142 } |
1150 | 1143 |
1151 | 1144 |
1145 void Heap::UpdateReferencesInExternalStringTable( | |
1146 ExternalStringTableUpdaterCallback updater_func) { | |
1147 | |
1148 // Update old space string references. | |
1149 if (external_string_table_.old_space_strings_.length() > 0) { | |
1150 Object** start = &external_string_table_.old_space_strings_[0]; | |
1151 Object** end = start + external_string_table_.old_space_strings_.length(); | |
1152 for (Object** p = start; p < end; ++p) *p = updater_func(this, p); | |
1153 } | |
1154 | |
1155 UpdateNewSpaceReferencesInExternalStringTable(updater_func); | |
1156 } | |
1157 | |
1158 | |
1152 static Object* ProcessFunctionWeakReferences(Heap* heap, | 1159 static Object* ProcessFunctionWeakReferences(Heap* heap, |
1153 Object* function, | 1160 Object* function, |
1154 WeakObjectRetainer* retainer) { | 1161 WeakObjectRetainer* retainer) { |
1155 Object* head = heap->undefined_value(); | 1162 Object* undefined = heap->undefined_value(); |
1163 Object* head = undefined; | |
1156 JSFunction* tail = NULL; | 1164 JSFunction* tail = NULL; |
1157 Object* candidate = function; | 1165 Object* candidate = function; |
1158 while (candidate != heap->undefined_value()) { | 1166 while (candidate != undefined) { |
1159 // Check whether to keep the candidate in the list. | 1167 // Check whether to keep the candidate in the list. |
1160 JSFunction* candidate_function = reinterpret_cast<JSFunction*>(candidate); | 1168 JSFunction* candidate_function = reinterpret_cast<JSFunction*>(candidate); |
1161 Object* retain = retainer->RetainAs(candidate); | 1169 Object* retain = retainer->RetainAs(candidate); |
1162 if (retain != NULL) { | 1170 if (retain != NULL) { |
1163 if (head == heap->undefined_value()) { | 1171 if (head == undefined) { |
1164 // First element in the list. | 1172 // First element in the list. |
1165 head = candidate_function; | 1173 head = retain; |
1166 } else { | 1174 } else { |
1167 // Subsequent elements in the list. | 1175 // Subsequent elements in the list. |
1168 ASSERT(tail != NULL); | 1176 ASSERT(tail != NULL); |
1169 tail->set_next_function_link(candidate_function); | 1177 tail->set_next_function_link(retain); |
1170 } | 1178 } |
1171 // Retained function is new tail. | 1179 // Retained function is new tail. |
1180 candidate_function = reinterpret_cast<JSFunction*>(retain); | |
1172 tail = candidate_function; | 1181 tail = candidate_function; |
1182 | |
1183 ASSERT(retain->IsUndefined() || retain->IsJSFunction()); | |
1184 | |
1185 if (retain == undefined) break; | |
1173 } | 1186 } |
1187 | |
1174 // Move to next element in the list. | 1188 // Move to next element in the list. |
1175 candidate = candidate_function->next_function_link(); | 1189 candidate = candidate_function->next_function_link(); |
1176 } | 1190 } |
1177 | 1191 |
1178 // Terminate the list if there is one or more elements. | 1192 // Terminate the list if there is one or more elements. |
1179 if (tail != NULL) { | 1193 if (tail != NULL) { |
1180 tail->set_next_function_link(heap->undefined_value()); | 1194 tail->set_next_function_link(undefined); |
1181 } | 1195 } |
1182 | 1196 |
1197 head->Verify(); | |
1198 | |
1183 return head; | 1199 return head; |
1184 } | 1200 } |
1185 | 1201 |
1186 | 1202 |
1187 void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { | 1203 void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) { |
1188 Object* head = undefined_value(); | 1204 Object* undefined = undefined_value(); |
1205 Object* head = undefined; | |
1189 Context* tail = NULL; | 1206 Context* tail = NULL; |
1190 Object* candidate = global_contexts_list_; | 1207 Object* candidate = global_contexts_list_; |
1191 while (candidate != undefined_value()) { | 1208 while (candidate != undefined) { |
1192 // Check whether to keep the candidate in the list. | 1209 // Check whether to keep the candidate in the list. |
1193 Context* candidate_context = reinterpret_cast<Context*>(candidate); | 1210 Context* candidate_context = reinterpret_cast<Context*>(candidate); |
1194 Object* retain = retainer->RetainAs(candidate); | 1211 Object* retain = retainer->RetainAs(candidate); |
1195 if (retain != NULL) { | 1212 if (retain != NULL) { |
1196 if (head == undefined_value()) { | 1213 if (head == undefined) { |
1197 // First element in the list. | 1214 // First element in the list. |
1198 head = candidate_context; | 1215 head = retain; |
1199 } else { | 1216 } else { |
1200 // Subsequent elements in the list. | 1217 // Subsequent elements in the list. |
1201 ASSERT(tail != NULL); | 1218 ASSERT(tail != NULL); |
1202 tail->set_unchecked(this, | 1219 tail->set_unchecked(this, |
1203 Context::NEXT_CONTEXT_LINK, | 1220 Context::NEXT_CONTEXT_LINK, |
1204 candidate_context, | 1221 retain, |
1205 UPDATE_WRITE_BARRIER); | 1222 UPDATE_WRITE_BARRIER); |
1206 } | 1223 } |
1207 // Retained context is new tail. | 1224 // Retained context is new tail. |
1225 candidate_context = reinterpret_cast<Context*>(retain); | |
1208 tail = candidate_context; | 1226 tail = candidate_context; |
1209 | 1227 |
1228 if (retain == undefined) break; | |
1229 | |
1210 // Process the weak list of optimized functions for the context. | 1230 // Process the weak list of optimized functions for the context. |
1211 Object* function_list_head = | 1231 Object* function_list_head = |
1212 ProcessFunctionWeakReferences( | 1232 ProcessFunctionWeakReferences( |
1213 this, | 1233 this, |
1214 candidate_context->get(Context::OPTIMIZED_FUNCTIONS_LIST), | 1234 candidate_context->get(Context::OPTIMIZED_FUNCTIONS_LIST), |
1215 retainer); | 1235 retainer); |
1216 candidate_context->set_unchecked(this, | 1236 candidate_context->set_unchecked(this, |
1217 Context::OPTIMIZED_FUNCTIONS_LIST, | 1237 Context::OPTIMIZED_FUNCTIONS_LIST, |
1218 function_list_head, | 1238 function_list_head, |
1219 UPDATE_WRITE_BARRIER); | 1239 UPDATE_WRITE_BARRIER); |
1220 } | 1240 } |
1241 | |
1221 // Move to next element in the list. | 1242 // Move to next element in the list. |
1222 candidate = candidate_context->get(Context::NEXT_CONTEXT_LINK); | 1243 candidate = candidate_context->get(Context::NEXT_CONTEXT_LINK); |
1223 } | 1244 } |
1224 | 1245 |
1225 // Terminate the list if there is one or more elements. | 1246 // Terminate the list if there is one or more elements. |
1226 if (tail != NULL) { | 1247 if (tail != NULL) { |
1227 tail->set_unchecked(this, | 1248 tail->set_unchecked(this, |
1228 Context::NEXT_CONTEXT_LINK, | 1249 Context::NEXT_CONTEXT_LINK, |
1229 Heap::undefined_value(), | 1250 Heap::undefined_value(), |
1230 UPDATE_WRITE_BARRIER); | 1251 UPDATE_WRITE_BARRIER); |
(...skipping 2822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4053 } | 4074 } |
4054 | 4075 |
4055 | 4076 |
4056 // This function expects that NewSpace's allocated objects histogram is | 4077 // This function expects that NewSpace's allocated objects histogram is |
4057 // populated (via a call to CollectStatistics or else as a side effect of a | 4078 // populated (via a call to CollectStatistics or else as a side effect of a |
4058 // just-completed scavenge collection). | 4079 // just-completed scavenge collection). |
4059 void Heap::ReportHeapStatistics(const char* title) { | 4080 void Heap::ReportHeapStatistics(const char* title) { |
4060 USE(title); | 4081 USE(title); |
4061 PrintF(">>>>>> =============== %s (%d) =============== >>>>>>\n", | 4082 PrintF(">>>>>> =============== %s (%d) =============== >>>>>>\n", |
4062 title, gc_count_); | 4083 title, gc_count_); |
4063 PrintF("mark-compact GC : %d\n", mc_count_); | |
4064 PrintF("old_gen_promotion_limit_ %" V8_PTR_PREFIX "d\n", | 4084 PrintF("old_gen_promotion_limit_ %" V8_PTR_PREFIX "d\n", |
4065 old_gen_promotion_limit_); | 4085 old_gen_promotion_limit_); |
4066 PrintF("old_gen_allocation_limit_ %" V8_PTR_PREFIX "d\n", | 4086 PrintF("old_gen_allocation_limit_ %" V8_PTR_PREFIX "d\n", |
4067 old_gen_allocation_limit_); | 4087 old_gen_allocation_limit_); |
4068 | 4088 |
4069 PrintF("\n"); | 4089 PrintF("\n"); |
4070 PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles()); | 4090 PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles()); |
4071 isolate_->global_handles()->PrintStats(); | 4091 isolate_->global_handles()->PrintStats(); |
4072 PrintF("\n"); | 4092 PrintF("\n"); |
4073 | 4093 |
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4949 reinterpret_cast<Object*>( | 4969 reinterpret_cast<Object*>( |
4950 (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag); | 4970 (isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag); |
4951 } | 4971 } |
4952 | 4972 |
4953 | 4973 |
4954 void Heap::TearDown() { | 4974 void Heap::TearDown() { |
4955 if (FLAG_print_cumulative_gc_stat) { | 4975 if (FLAG_print_cumulative_gc_stat) { |
4956 PrintF("\n\n"); | 4976 PrintF("\n\n"); |
4957 PrintF("gc_count=%d ", gc_count_); | 4977 PrintF("gc_count=%d ", gc_count_); |
4958 PrintF("mark_sweep_count=%d ", ms_count_); | 4978 PrintF("mark_sweep_count=%d ", ms_count_); |
4959 PrintF("mark_compact_count=%d ", mc_count_); | |
4960 PrintF("max_gc_pause=%d ", get_max_gc_pause()); | 4979 PrintF("max_gc_pause=%d ", get_max_gc_pause()); |
4961 PrintF("min_in_mutator=%d ", get_min_in_mutator()); | 4980 PrintF("min_in_mutator=%d ", get_min_in_mutator()); |
4962 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", | 4981 PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", |
4963 get_max_alive_after_gc()); | 4982 get_max_alive_after_gc()); |
4964 PrintF("\n\n"); | 4983 PrintF("\n\n"); |
4965 } | 4984 } |
4966 | 4985 |
4967 isolate_->global_handles()->TearDown(); | 4986 isolate_->global_handles()->TearDown(); |
4968 | 4987 |
4969 external_string_table_.TearDown(); | 4988 external_string_table_.TearDown(); |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5424 MarkVisitor mark_visitor(this); | 5443 MarkVisitor mark_visitor(this); |
5425 MarkRecursively(root, &mark_visitor); | 5444 MarkRecursively(root, &mark_visitor); |
5426 | 5445 |
5427 UnmarkVisitor unmark_visitor(this); | 5446 UnmarkVisitor unmark_visitor(this); |
5428 UnmarkRecursively(root, &unmark_visitor); | 5447 UnmarkRecursively(root, &unmark_visitor); |
5429 | 5448 |
5430 ProcessResults(); | 5449 ProcessResults(); |
5431 } | 5450 } |
5432 | 5451 |
5433 | 5452 |
5453 static bool SafeIsGlobalContext(HeapObject* obj) { | |
5454 return obj->map() == obj->GetHeap()->raw_unchecked_global_context_map(); | |
5455 } | |
5456 | |
Erik Corry
2011/06/20 20:41:26
missing blank line
Vyacheslav Egorov (Chromium)
2011/06/21 11:44:48
Done.
| |
5434 void PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) { | 5457 void PathTracer::MarkRecursively(Object** p, MarkVisitor* mark_visitor) { |
5435 if (!(*p)->IsHeapObject()) return; | 5458 if (!(*p)->IsHeapObject()) return; |
5436 | 5459 |
5437 HeapObject* obj = HeapObject::cast(*p); | 5460 HeapObject* obj = HeapObject::cast(*p); |
5438 | 5461 |
5439 Object* map = obj->map(); | 5462 Object* map = obj->map(); |
5440 | 5463 |
5441 if (!map->IsHeapObject()) return; // visited before | 5464 if (!map->IsHeapObject()) return; // visited before |
5442 | 5465 |
5443 if (found_target_in_trace_) return; // stop if target found | 5466 if (found_target_in_trace_) return; // stop if target found |
5444 object_stack_.Add(obj); | 5467 object_stack_.Add(obj); |
5445 if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) || | 5468 if (((search_target_ == kAnyGlobalObject) && obj->IsJSGlobalObject()) || |
5446 (obj == search_target_)) { | 5469 (obj == search_target_)) { |
5447 found_target_in_trace_ = true; | 5470 found_target_in_trace_ = true; |
5448 found_target_ = true; | 5471 found_target_ = true; |
5449 return; | 5472 return; |
5450 } | 5473 } |
5451 | 5474 |
5452 bool is_global_context = obj->IsGlobalContext(); | 5475 bool is_global_context = SafeIsGlobalContext(obj); |
5453 | 5476 |
5454 // not visited yet | 5477 // not visited yet |
5455 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); | 5478 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); |
5456 | 5479 |
5457 Address map_addr = map_p->address(); | 5480 Address map_addr = map_p->address(); |
5458 | 5481 |
5459 obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag)); | 5482 obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag)); |
5460 | 5483 |
5461 // Scan the object body. | 5484 // Scan the object body. |
5462 if (is_global_context && (visit_mode_ == VISIT_ONLY_STRONG)) { | 5485 if (is_global_context && (visit_mode_ == VISIT_ONLY_STRONG)) { |
(...skipping 24 matching lines...) Expand all Loading... | |
5487 HeapObject* obj = HeapObject::cast(*p); | 5510 HeapObject* obj = HeapObject::cast(*p); |
5488 | 5511 |
5489 Object* map = obj->map(); | 5512 Object* map = obj->map(); |
5490 | 5513 |
5491 if (map->IsHeapObject()) return; // unmarked already | 5514 if (map->IsHeapObject()) return; // unmarked already |
5492 | 5515 |
5493 Address map_addr = reinterpret_cast<Address>(map); | 5516 Address map_addr = reinterpret_cast<Address>(map); |
5494 | 5517 |
5495 map_addr -= kMarkTag; | 5518 map_addr -= kMarkTag; |
5496 | 5519 |
5497 ASSERT_TAG_ALIGNED(map_addr); | 5520 // ASSERT_TAG_ALIGNED(map_addr); |
Erik Corry
2011/06/20 20:41:26
commented code
Vyacheslav Egorov (Chromium)
2011/06/21 11:44:48
Done.
| |
5498 | 5521 |
5499 HeapObject* map_p = HeapObject::FromAddress(map_addr); | 5522 HeapObject* map_p = HeapObject::FromAddress(map_addr); |
5500 | 5523 |
5501 obj->set_map(reinterpret_cast<Map*>(map_p)); | 5524 obj->set_map(reinterpret_cast<Map*>(map_p)); |
5502 | 5525 |
5503 UnmarkRecursively(reinterpret_cast<Object**>(&map_p), unmark_visitor); | 5526 UnmarkRecursively(reinterpret_cast<Object**>(&map_p), unmark_visitor); |
5504 | 5527 |
5505 obj->IterateBody(Map::cast(map_p)->instance_type(), | 5528 obj->IterateBody(Map::cast(map_p)->instance_type(), |
5506 obj->SizeFromMap(Map::cast(map_p)), | 5529 obj->SizeFromMap(Map::cast(map_p)), |
5507 unmark_visitor); | 5530 unmark_visitor); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5561 } | 5584 } |
5562 return holes_size; | 5585 return holes_size; |
5563 } | 5586 } |
5564 | 5587 |
5565 | 5588 |
5566 GCTracer::GCTracer(Heap* heap) | 5589 GCTracer::GCTracer(Heap* heap) |
5567 : start_time_(0.0), | 5590 : start_time_(0.0), |
5568 start_size_(0), | 5591 start_size_(0), |
5569 gc_count_(0), | 5592 gc_count_(0), |
5570 full_gc_count_(0), | 5593 full_gc_count_(0), |
5571 is_compacting_(false), | |
5572 marked_count_(0), | |
5573 allocated_since_last_gc_(0), | 5594 allocated_since_last_gc_(0), |
5574 spent_in_mutator_(0), | 5595 spent_in_mutator_(0), |
5575 promoted_objects_size_(0), | 5596 promoted_objects_size_(0), |
5576 heap_(heap) { | 5597 heap_(heap) { |
5577 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; | 5598 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; |
5578 start_time_ = OS::TimeCurrentMillis(); | 5599 start_time_ = OS::TimeCurrentMillis(); |
5579 start_size_ = heap_->SizeOfObjects(); | 5600 start_size_ = heap_->SizeOfObjects(); |
5580 | 5601 |
5581 for (int i = 0; i < Scope::kNumberOfScopes; i++) { | 5602 for (int i = 0; i < Scope::kNumberOfScopes; i++) { |
5582 scopes_[i] = 0; | 5603 scopes_[i] = 0; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5638 PrintF("pause=%d ", time); | 5659 PrintF("pause=%d ", time); |
5639 PrintF("mutator=%d ", | 5660 PrintF("mutator=%d ", |
5640 static_cast<int>(spent_in_mutator_)); | 5661 static_cast<int>(spent_in_mutator_)); |
5641 | 5662 |
5642 PrintF("gc="); | 5663 PrintF("gc="); |
5643 switch (collector_) { | 5664 switch (collector_) { |
5644 case SCAVENGER: | 5665 case SCAVENGER: |
5645 PrintF("s"); | 5666 PrintF("s"); |
5646 break; | 5667 break; |
5647 case MARK_COMPACTOR: | 5668 case MARK_COMPACTOR: |
5648 PrintF("%s", | 5669 PrintF("%s", "ms"); |
5649 heap_->mark_compact_collector_.HasCompacted() ? "mc" : "ms"); | |
5650 break; | 5670 break; |
5651 default: | 5671 default: |
5652 UNREACHABLE(); | 5672 UNREACHABLE(); |
5653 } | 5673 } |
5654 PrintF(" "); | 5674 PrintF(" "); |
5655 | 5675 |
5656 PrintF("external=%d ", static_cast<int>(scopes_[Scope::EXTERNAL])); | 5676 PrintF("external=%d ", static_cast<int>(scopes_[Scope::EXTERNAL])); |
5657 PrintF("mark=%d ", static_cast<int>(scopes_[Scope::MC_MARK])); | 5677 PrintF("mark=%d ", static_cast<int>(scopes_[Scope::MC_MARK])); |
5658 PrintF("sweep=%d ", static_cast<int>(scopes_[Scope::MC_SWEEP])); | 5678 PrintF("sweep=%d ", static_cast<int>(scopes_[Scope::MC_SWEEP])); |
5659 PrintF("sweepns=%d ", static_cast<int>(scopes_[Scope::MC_SWEEP_NEWSPACE])); | 5679 PrintF("sweepns=%d ", static_cast<int>(scopes_[Scope::MC_SWEEP_NEWSPACE])); |
(...skipping 17 matching lines...) Expand all Loading... | |
5677 heap_->PrintShortHeapStatistics(); | 5697 heap_->PrintShortHeapStatistics(); |
5678 #endif | 5698 #endif |
5679 } | 5699 } |
5680 | 5700 |
5681 | 5701 |
5682 const char* GCTracer::CollectorString() { | 5702 const char* GCTracer::CollectorString() { |
5683 switch (collector_) { | 5703 switch (collector_) { |
5684 case SCAVENGER: | 5704 case SCAVENGER: |
5685 return "Scavenge"; | 5705 return "Scavenge"; |
5686 case MARK_COMPACTOR: | 5706 case MARK_COMPACTOR: |
5687 return heap_->mark_compact_collector_.HasCompacted() ? "Mark-compact" | 5707 return "Mark-sweep"; |
5688 : "Mark-sweep"; | |
5689 } | 5708 } |
5690 return "Unknown GC"; | 5709 return "Unknown GC"; |
5691 } | 5710 } |
5692 | 5711 |
5693 | 5712 |
5694 int KeyedLookupCache::Hash(Map* map, String* name) { | 5713 int KeyedLookupCache::Hash(Map* map, String* name) { |
5695 // Uses only lower 32 bits if pointers are larger. | 5714 // Uses only lower 32 bits if pointers are larger. |
5696 uintptr_t addr_hash = | 5715 uintptr_t addr_hash = |
5697 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)) >> kMapHashShift; | 5716 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(map)) >> kMapHashShift; |
5698 return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask); | 5717 return static_cast<uint32_t>((addr_hash ^ name->Hash()) & kCapacityMask); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5786 } | 5805 } |
5787 | 5806 |
5788 | 5807 |
5789 void ExternalStringTable::TearDown() { | 5808 void ExternalStringTable::TearDown() { |
5790 new_space_strings_.Free(); | 5809 new_space_strings_.Free(); |
5791 old_space_strings_.Free(); | 5810 old_space_strings_.Free(); |
5792 } | 5811 } |
5793 | 5812 |
5794 | 5813 |
5795 } } // namespace v8::internal | 5814 } } // namespace v8::internal |
OLD | NEW |