| 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 old_gen_allocation_limit_(kMinimumAllocationLimit), | 124 old_gen_allocation_limit_(kMinimumAllocationLimit), |
| 125 external_allocation_limit_(0), | 125 external_allocation_limit_(0), |
| 126 amount_of_external_allocated_memory_(0), | 126 amount_of_external_allocated_memory_(0), |
| 127 amount_of_external_allocated_memory_at_last_global_gc_(0), | 127 amount_of_external_allocated_memory_at_last_global_gc_(0), |
| 128 old_gen_exhausted_(false), | 128 old_gen_exhausted_(false), |
| 129 store_buffer_rebuilder_(store_buffer()), | 129 store_buffer_rebuilder_(store_buffer()), |
| 130 hidden_symbol_(NULL), | 130 hidden_symbol_(NULL), |
| 131 global_gc_prologue_callback_(NULL), | 131 global_gc_prologue_callback_(NULL), |
| 132 global_gc_epilogue_callback_(NULL), | 132 global_gc_epilogue_callback_(NULL), |
| 133 gc_safe_size_of_old_object_(NULL), | 133 gc_safe_size_of_old_object_(NULL), |
| 134 total_regexp_code_generated_(0), |
| 134 tracer_(NULL), | 135 tracer_(NULL), |
| 135 young_survivors_after_last_gc_(0), | 136 young_survivors_after_last_gc_(0), |
| 136 high_survival_rate_period_length_(0), | 137 high_survival_rate_period_length_(0), |
| 137 survival_rate_(0), | 138 survival_rate_(0), |
| 138 previous_survival_rate_trend_(Heap::STABLE), | 139 previous_survival_rate_trend_(Heap::STABLE), |
| 139 survival_rate_trend_(Heap::STABLE), | 140 survival_rate_trend_(Heap::STABLE), |
| 140 max_gc_pause_(0), | 141 max_gc_pause_(0), |
| 141 max_alive_after_gc_(0), | 142 max_alive_after_gc_(0), |
| 142 min_in_mutator_(kMaxInt), | 143 min_in_mutator_(kMaxInt), |
| 143 alive_after_last_gc_(0), | 144 alive_after_last_gc_(0), |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 } else { | 755 } else { |
| 755 tracer_ = tracer; | 756 tracer_ = tracer; |
| 756 Scavenge(); | 757 Scavenge(); |
| 757 tracer_ = NULL; | 758 tracer_ = NULL; |
| 758 | 759 |
| 759 UpdateSurvivalRateTrend(start_new_space_size); | 760 UpdateSurvivalRateTrend(start_new_space_size); |
| 760 } | 761 } |
| 761 | 762 |
| 762 isolate_->counters()->objs_since_last_young()->Set(0); | 763 isolate_->counters()->objs_since_last_young()->Set(0); |
| 763 | 764 |
| 764 if (collector == MARK_COMPACTOR) { | 765 { DisableAssertNoAllocation allow_allocation; |
| 765 DisableAssertNoAllocation allow_allocation; | |
| 766 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 766 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
| 767 next_gc_likely_to_collect_more = | 767 next_gc_likely_to_collect_more = |
| 768 isolate_->global_handles()->PostGarbageCollectionProcessing(); | 768 isolate_->global_handles()->PostGarbageCollectionProcessing(collector); |
| 769 } | 769 } |
| 770 | 770 |
| 771 // Update relocatables. | 771 // Update relocatables. |
| 772 Relocatable::PostGarbageCollectionProcessing(); | 772 Relocatable::PostGarbageCollectionProcessing(); |
| 773 | 773 |
| 774 if (collector == MARK_COMPACTOR) { | 774 if (collector == MARK_COMPACTOR) { |
| 775 // Register the amount of external allocated memory. | 775 // Register the amount of external allocated memory. |
| 776 amount_of_external_allocated_memory_at_last_global_gc_ = | 776 amount_of_external_allocated_memory_at_last_global_gc_ = |
| 777 amount_of_external_allocated_memory_; | 777 amount_of_external_allocated_memory_; |
| 778 } | 778 } |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 if (new_space_.Capacity() < new_space_.MaximumCapacity() && | 920 if (new_space_.Capacity() < new_space_.MaximumCapacity() && |
| 921 survived_since_last_expansion_ > new_space_.Capacity()) { | 921 survived_since_last_expansion_ > new_space_.Capacity()) { |
| 922 // Grow the size of new space if there is room to grow and enough | 922 // Grow the size of new space if there is room to grow and enough |
| 923 // data has survived scavenge since the last expansion. | 923 // data has survived scavenge since the last expansion. |
| 924 new_space_.Grow(); | 924 new_space_.Grow(); |
| 925 survived_since_last_expansion_ = 0; | 925 survived_since_last_expansion_ = 0; |
| 926 } | 926 } |
| 927 } | 927 } |
| 928 | 928 |
| 929 | 929 |
| 930 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { |
| 931 return heap->InNewSpace(*p) && |
| 932 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); |
| 933 } |
| 934 |
| 935 |
| 930 void Heap::ScavengeStoreBufferCallback( | 936 void Heap::ScavengeStoreBufferCallback( |
| 931 Heap* heap, | 937 Heap* heap, |
| 932 MemoryChunk* page, | 938 MemoryChunk* page, |
| 933 StoreBufferEvent event) { | 939 StoreBufferEvent event) { |
| 934 heap->store_buffer_rebuilder_.Callback(page, event); | 940 heap->store_buffer_rebuilder_.Callback(page, event); |
| 935 } | 941 } |
| 936 | 942 |
| 937 | 943 |
| 938 void StoreBufferRebuilder::Callback(MemoryChunk* page, StoreBufferEvent event) { | 944 void StoreBufferRebuilder::Callback(MemoryChunk* page, StoreBufferEvent event) { |
| 939 if (event == kStoreBufferStartScanningPagesEvent) { | 945 if (event == kStoreBufferStartScanningPagesEvent) { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 reinterpret_cast<Address>(cell) + | 1066 reinterpret_cast<Address>(cell) + |
| 1061 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); | 1067 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); |
| 1062 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); | 1068 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); |
| 1063 } | 1069 } |
| 1064 } | 1070 } |
| 1065 | 1071 |
| 1066 // Scavenge object reachable from the global contexts list directly. | 1072 // Scavenge object reachable from the global contexts list directly. |
| 1067 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); | 1073 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); |
| 1068 | 1074 |
| 1069 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1075 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1076 isolate_->global_handles()->IdentifyWeakIndependentHandles( |
| 1077 &IsUnscavengedHeapObject); |
| 1078 isolate_->global_handles()->IterateWeakIndependentRoots(&scavenge_visitor); |
| 1079 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1080 |
| 1070 | 1081 |
| 1071 UpdateNewSpaceReferencesInExternalStringTable( | 1082 UpdateNewSpaceReferencesInExternalStringTable( |
| 1072 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1083 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1073 | 1084 |
| 1074 LiveObjectList::UpdateReferencesForScavengeGC(); | 1085 LiveObjectList::UpdateReferencesForScavengeGC(); |
| 1075 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); | 1086 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
| 1076 incremental_marking()->UpdateMarkingDequeAfterScavenge(); | 1087 incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
| 1077 | 1088 |
| 1078 ASSERT(new_space_front == new_space_.top()); | 1089 ASSERT(new_space_front == new_space_.top()); |
| 1079 | 1090 |
| (...skipping 1355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2435 share->set_inferred_name(empty_string()); | 2446 share->set_inferred_name(empty_string()); |
| 2436 share->set_compiler_hints(0); | 2447 share->set_compiler_hints(0); |
| 2437 share->set_deopt_counter(Smi::FromInt(FLAG_deopt_every_n_times)); | 2448 share->set_deopt_counter(Smi::FromInt(FLAG_deopt_every_n_times)); |
| 2438 share->set_initial_map(undefined_value()); | 2449 share->set_initial_map(undefined_value()); |
| 2439 share->set_this_property_assignments_count(0); | 2450 share->set_this_property_assignments_count(0); |
| 2440 share->set_this_property_assignments(undefined_value()); | 2451 share->set_this_property_assignments(undefined_value()); |
| 2441 share->set_opt_count(0); | 2452 share->set_opt_count(0); |
| 2442 share->set_num_literals(0); | 2453 share->set_num_literals(0); |
| 2443 share->set_end_position(0); | 2454 share->set_end_position(0); |
| 2444 share->set_function_token_position(0); | 2455 share->set_function_token_position(0); |
| 2456 share->set_es5_native(false); |
| 2445 return result; | 2457 return result; |
| 2446 } | 2458 } |
| 2447 | 2459 |
| 2448 | 2460 |
| 2449 MaybeObject* Heap::AllocateJSMessageObject(String* type, | 2461 MaybeObject* Heap::AllocateJSMessageObject(String* type, |
| 2450 JSArray* arguments, | 2462 JSArray* arguments, |
| 2451 int start_position, | 2463 int start_position, |
| 2452 int end_position, | 2464 int end_position, |
| 2453 Object* script, | 2465 Object* script, |
| 2454 Object* stack_trace, | 2466 Object* stack_trace, |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2857 Code* code = Code::cast(result); | 2869 Code* code = Code::cast(result); |
| 2858 ASSERT(!isolate_->code_range()->exists() || | 2870 ASSERT(!isolate_->code_range()->exists() || |
| 2859 isolate_->code_range()->contains(code->address())); | 2871 isolate_->code_range()->contains(code->address())); |
| 2860 code->set_instruction_size(desc.instr_size); | 2872 code->set_instruction_size(desc.instr_size); |
| 2861 code->set_relocation_info(ByteArray::cast(reloc_info)); | 2873 code->set_relocation_info(ByteArray::cast(reloc_info)); |
| 2862 code->set_flags(flags); | 2874 code->set_flags(flags); |
| 2863 if (code->is_call_stub() || code->is_keyed_call_stub()) { | 2875 if (code->is_call_stub() || code->is_keyed_call_stub()) { |
| 2864 code->set_check_type(RECEIVER_MAP_CHECK); | 2876 code->set_check_type(RECEIVER_MAP_CHECK); |
| 2865 } | 2877 } |
| 2866 code->set_deoptimization_data(empty_fixed_array()); | 2878 code->set_deoptimization_data(empty_fixed_array()); |
| 2879 code->set_next_code_flushing_candidate(undefined_value()); |
| 2867 // Allow self references to created code object by patching the handle to | 2880 // Allow self references to created code object by patching the handle to |
| 2868 // point to the newly allocated Code object. | 2881 // point to the newly allocated Code object. |
| 2869 if (!self_reference.is_null()) { | 2882 if (!self_reference.is_null()) { |
| 2870 *(self_reference.location()) = code; | 2883 *(self_reference.location()) = code; |
| 2871 } | 2884 } |
| 2872 // Migrate generated code. | 2885 // Migrate generated code. |
| 2873 // The generated code can contain Object** values (typically from handles) | 2886 // The generated code can contain Object** values (typically from handles) |
| 2874 // that are dereferenced during the copy to point directly to the actual heap | 2887 // that are dereferenced during the copy to point directly to the actual heap |
| 2875 // objects. These pointers can include references to the code object itself, | 2888 // objects. These pointers can include references to the code object itself, |
| 2876 // through the self_reference parameter. | 2889 // through the self_reference parameter. |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3269 AllocateJSObjectFromMap(constructor->initial_map(), pretenure); | 3282 AllocateJSObjectFromMap(constructor->initial_map(), pretenure); |
| 3270 #ifdef DEBUG | 3283 #ifdef DEBUG |
| 3271 // Make sure result is NOT a global object if valid. | 3284 // Make sure result is NOT a global object if valid. |
| 3272 Object* non_failure; | 3285 Object* non_failure; |
| 3273 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); | 3286 ASSERT(!result->ToObject(&non_failure) || !non_failure->IsGlobalObject()); |
| 3274 #endif | 3287 #endif |
| 3275 return result; | 3288 return result; |
| 3276 } | 3289 } |
| 3277 | 3290 |
| 3278 | 3291 |
| 3292 MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) { |
| 3293 // Allocate map. |
| 3294 // TODO(rossberg): Once we optimize proxies, think about a scheme to share |
| 3295 // maps. Will probably depend on the identity of the handler object, too. |
| 3296 Object* map_obj; |
| 3297 MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize); |
| 3298 if (!maybe_map_obj->ToObject(&map_obj)) return maybe_map_obj; |
| 3299 Map* map = Map::cast(map_obj); |
| 3300 map->set_prototype(prototype); |
| 3301 map->set_pre_allocated_property_fields(1); |
| 3302 map->set_inobject_properties(1); |
| 3303 |
| 3304 // Allocate the proxy object. |
| 3305 Object* result; |
| 3306 MaybeObject* maybe_result = Allocate(map, NEW_SPACE); |
| 3307 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3308 JSProxy::cast(result)->set_handler(handler); |
| 3309 return result; |
| 3310 } |
| 3311 |
| 3312 |
| 3279 MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) { | 3313 MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) { |
| 3280 ASSERT(constructor->has_initial_map()); | 3314 ASSERT(constructor->has_initial_map()); |
| 3281 Map* map = constructor->initial_map(); | 3315 Map* map = constructor->initial_map(); |
| 3282 | 3316 |
| 3283 // Make sure no field properties are described in the initial map. | 3317 // Make sure no field properties are described in the initial map. |
| 3284 // This guarantees us that normalizing the properties does not | 3318 // This guarantees us that normalizing the properties does not |
| 3285 // require us to change property values to JSGlobalPropertyCells. | 3319 // require us to change property values to JSGlobalPropertyCells. |
| 3286 ASSERT(map->NextFreePropertyIndex() == 0); | 3320 ASSERT(map->NextFreePropertyIndex() == 0); |
| 3287 | 3321 |
| 3288 // Make sure we don't have a ton of pre-allocated slots in the | 3322 // Make sure we don't have a ton of pre-allocated slots in the |
| (...skipping 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4617 | 4651 |
| 4618 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { | 4652 void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) { |
| 4619 IterateStrongRoots(v, mode); | 4653 IterateStrongRoots(v, mode); |
| 4620 IterateWeakRoots(v, mode); | 4654 IterateWeakRoots(v, mode); |
| 4621 } | 4655 } |
| 4622 | 4656 |
| 4623 | 4657 |
| 4624 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { | 4658 void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) { |
| 4625 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); | 4659 v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex])); |
| 4626 v->Synchronize("symbol_table"); | 4660 v->Synchronize("symbol_table"); |
| 4627 if (mode != VISIT_ALL_IN_SCAVENGE) { | 4661 if (mode != VISIT_ALL_IN_SCAVENGE && |
| 4662 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { |
| 4628 // Scavenge collections have special processing for this. | 4663 // Scavenge collections have special processing for this. |
| 4629 external_string_table_.Iterate(v); | 4664 external_string_table_.Iterate(v); |
| 4630 } | 4665 } |
| 4631 v->Synchronize("external_string_table"); | 4666 v->Synchronize("external_string_table"); |
| 4632 } | 4667 } |
| 4633 | 4668 |
| 4634 | 4669 |
| 4635 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { | 4670 void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) { |
| 4636 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); | 4671 v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]); |
| 4637 v->Synchronize("strong_root_list"); | 4672 v->Synchronize("strong_root_list"); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4653 isolate_->compilation_cache()->Iterate(v); | 4688 isolate_->compilation_cache()->Iterate(v); |
| 4654 v->Synchronize("compilationcache"); | 4689 v->Synchronize("compilationcache"); |
| 4655 | 4690 |
| 4656 // Iterate over local handles in handle scopes. | 4691 // Iterate over local handles in handle scopes. |
| 4657 isolate_->handle_scope_implementer()->Iterate(v); | 4692 isolate_->handle_scope_implementer()->Iterate(v); |
| 4658 v->Synchronize("handlescope"); | 4693 v->Synchronize("handlescope"); |
| 4659 | 4694 |
| 4660 // Iterate over the builtin code objects and code stubs in the | 4695 // Iterate over the builtin code objects and code stubs in the |
| 4661 // heap. Note that it is not necessary to iterate over code objects | 4696 // heap. Note that it is not necessary to iterate over code objects |
| 4662 // on scavenge collections. | 4697 // on scavenge collections. |
| 4663 if (mode != VISIT_ALL_IN_SCAVENGE) { | 4698 if (mode != VISIT_ALL_IN_SCAVENGE && |
| 4699 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { |
| 4664 isolate_->builtins()->IterateBuiltins(v); | 4700 isolate_->builtins()->IterateBuiltins(v); |
| 4665 } | 4701 } |
| 4666 v->Synchronize("builtins"); | 4702 v->Synchronize("builtins"); |
| 4667 | 4703 |
| 4668 // Iterate over global handles. | 4704 // Iterate over global handles. |
| 4669 if (mode == VISIT_ONLY_STRONG) { | 4705 switch (mode) { |
| 4670 isolate_->global_handles()->IterateStrongRoots(v); | 4706 case VISIT_ONLY_STRONG: |
| 4671 } else { | 4707 isolate_->global_handles()->IterateStrongRoots(v); |
| 4672 isolate_->global_handles()->IterateAllRoots(v); | 4708 break; |
| 4709 case VISIT_ALL_IN_SCAVENGE: |
| 4710 isolate_->global_handles()->IterateStrongAndDependentRoots(v); |
| 4711 break; |
| 4712 case VISIT_ALL_IN_SWEEP_NEWSPACE: |
| 4713 case VISIT_ALL: |
| 4714 isolate_->global_handles()->IterateAllRoots(v); |
| 4715 break; |
| 4673 } | 4716 } |
| 4674 v->Synchronize("globalhandles"); | 4717 v->Synchronize("globalhandles"); |
| 4675 | 4718 |
| 4676 // Iterate over pointers being held by inactive threads. | 4719 // Iterate over pointers being held by inactive threads. |
| 4677 isolate_->thread_manager()->Iterate(v); | 4720 isolate_->thread_manager()->Iterate(v); |
| 4678 v->Synchronize("threadmanager"); | 4721 v->Synchronize("threadmanager"); |
| 4679 | 4722 |
| 4680 // Iterate over the pointers the Serialization/Deserialization code is | 4723 // Iterate over the pointers the Serialization/Deserialization code is |
| 4681 // holding. | 4724 // holding. |
| 4682 // During garbage collection this keeps the partial snapshot cache alive. | 4725 // During garbage collection this keeps the partial snapshot cache alive. |
| (...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5942 } | 5985 } |
| 5943 | 5986 |
| 5944 | 5987 |
| 5945 void ExternalStringTable::TearDown() { | 5988 void ExternalStringTable::TearDown() { |
| 5946 new_space_strings_.Free(); | 5989 new_space_strings_.Free(); |
| 5947 old_space_strings_.Free(); | 5990 old_space_strings_.Free(); |
| 5948 } | 5991 } |
| 5949 | 5992 |
| 5950 | 5993 |
| 5951 } } // namespace v8::internal | 5994 } } // namespace v8::internal |
| OLD | NEW |