| 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 15 matching lines...) Expand all Loading... |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "accessors.h" | 30 #include "accessors.h" |
| 31 #include "api.h" | 31 #include "api.h" |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "codegen.h" | 33 #include "codegen.h" |
| 34 #include "compilation-cache.h" | 34 #include "compilation-cache.h" |
| 35 #include "debug.h" | 35 #include "debug.h" |
| 36 #include "deoptimizer.h" |
| 36 #include "global-handles.h" | 37 #include "global-handles.h" |
| 37 #include "heap-profiler.h" | 38 #include "heap-profiler.h" |
| 38 #include "incremental-marking.h" | 39 #include "incremental-marking.h" |
| 39 #include "liveobjectlist-inl.h" | 40 #include "liveobjectlist-inl.h" |
| 40 #include "mark-compact.h" | 41 #include "mark-compact.h" |
| 41 #include "natives.h" | 42 #include "natives.h" |
| 42 #include "objects-visiting.h" | 43 #include "objects-visiting.h" |
| 43 #include "objects-visiting-inl.h" | 44 #include "objects-visiting-inl.h" |
| 44 #include "runtime-profiler.h" | 45 #include "runtime-profiler.h" |
| 45 #include "scanner-base.h" | 46 #include "scanner-base.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 max_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)), | 89 max_semispace_size_(8 * Max(LUMP_OF_MEMORY, Page::kPageSize)), |
| 89 initial_semispace_size_(Max(LUMP_OF_MEMORY, Page::kPageSize)), | 90 initial_semispace_size_(Max(LUMP_OF_MEMORY, Page::kPageSize)), |
| 90 max_old_generation_size_(1024ul * LUMP_OF_MEMORY), | 91 max_old_generation_size_(1024ul * LUMP_OF_MEMORY), |
| 91 max_executable_size_(256l * LUMP_OF_MEMORY), | 92 max_executable_size_(256l * LUMP_OF_MEMORY), |
| 92 | 93 |
| 93 // Variables set based on semispace_size_ and old_generation_size_ in | 94 // Variables set based on semispace_size_ and old_generation_size_ in |
| 94 // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) | 95 // ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_) |
| 95 // Will be 4 * reserved_semispace_size_ to ensure that young | 96 // Will be 4 * reserved_semispace_size_ to ensure that young |
| 96 // generation can be aligned to its size. | 97 // generation can be aligned to its size. |
| 97 survived_since_last_expansion_(0), | 98 survived_since_last_expansion_(0), |
| 99 sweep_generation_(0), |
| 98 always_allocate_scope_depth_(0), | 100 always_allocate_scope_depth_(0), |
| 99 linear_allocation_scope_depth_(0), | 101 linear_allocation_scope_depth_(0), |
| 100 contexts_disposed_(0), | 102 contexts_disposed_(0), |
| 101 scan_on_scavenge_pages_(0), | 103 scan_on_scavenge_pages_(0), |
| 102 new_space_(this), | 104 new_space_(this), |
| 103 old_pointer_space_(NULL), | 105 old_pointer_space_(NULL), |
| 104 old_data_space_(NULL), | 106 old_data_space_(NULL), |
| 105 code_space_(NULL), | 107 code_space_(NULL), |
| 106 map_space_(NULL), | 108 map_space_(NULL), |
| 107 cell_space_(NULL), | 109 cell_space_(NULL), |
| 108 lo_space_(NULL), | 110 lo_space_(NULL), |
| 109 gc_state_(NOT_IN_GC), | 111 gc_state_(NOT_IN_GC), |
| 112 gc_post_processing_depth_(0), |
| 110 ms_count_(0), | 113 ms_count_(0), |
| 111 gc_count_(0), | 114 gc_count_(0), |
| 112 unflattened_strings_length_(0), | 115 unflattened_strings_length_(0), |
| 113 #ifdef DEBUG | 116 #ifdef DEBUG |
| 114 allocation_allowed_(true), | 117 allocation_allowed_(true), |
| 115 allocation_timeout_(0), | 118 allocation_timeout_(0), |
| 116 disallow_allocation_failure_(false), | 119 disallow_allocation_failure_(false), |
| 117 debug_utils_(NULL), | 120 debug_utils_(NULL), |
| 118 #endif // DEBUG | 121 #endif // DEBUG |
| 119 old_gen_promotion_limit_(kMinimumPromotionLimit), | 122 old_gen_promotion_limit_(kMinimumPromotionLimit), |
| (...skipping 28 matching lines...) Expand all Loading... |
| 148 configured_(false), | 151 configured_(false), |
| 149 last_empty_page_was_given_back_to_the_os_(false), | 152 last_empty_page_was_given_back_to_the_os_(false), |
| 150 chunks_queued_for_free_(NULL) { | 153 chunks_queued_for_free_(NULL) { |
| 151 // Allow build-time customization of the max semispace size. Building | 154 // Allow build-time customization of the max semispace size. Building |
| 152 // V8 with snapshots and a non-default max semispace size is much | 155 // 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. | 156 // easier if you can define it as part of the build environment. |
| 154 #if defined(V8_MAX_SEMISPACE_SIZE) | 157 #if defined(V8_MAX_SEMISPACE_SIZE) |
| 155 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; | 158 max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE; |
| 156 #endif | 159 #endif |
| 157 | 160 |
| 161 intptr_t max_virtual = OS::MaxVirtualMemory(); |
| 162 |
| 163 if (max_virtual > 0) { |
| 164 if (code_range_size_ > 0) { |
| 165 // Reserve no more than 1/8 of the memory for the code range. |
| 166 code_range_size_ = Min(code_range_size_, max_virtual >> 3); |
| 167 } |
| 168 } |
| 169 |
| 158 memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); | 170 memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); |
| 159 global_contexts_list_ = NULL; | 171 global_contexts_list_ = NULL; |
| 160 mark_compact_collector_.heap_ = this; | 172 mark_compact_collector_.heap_ = this; |
| 161 external_string_table_.heap_ = this; | 173 external_string_table_.heap_ = this; |
| 162 } | 174 } |
| 163 | 175 |
| 164 | 176 |
| 165 intptr_t Heap::Capacity() { | 177 intptr_t Heap::Capacity() { |
| 166 if (!HasBeenSetup()) return 0; | 178 if (!HasBeenSetup()) return 0; |
| 167 | 179 |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 ? isolate_->counters()->gc_scavenger() | 517 ? isolate_->counters()->gc_scavenger() |
| 506 : isolate_->counters()->gc_compactor(); | 518 : isolate_->counters()->gc_compactor(); |
| 507 rate->Start(); | 519 rate->Start(); |
| 508 next_gc_likely_to_collect_more = | 520 next_gc_likely_to_collect_more = |
| 509 PerformGarbageCollection(collector, &tracer); | 521 PerformGarbageCollection(collector, &tracer); |
| 510 rate->Stop(); | 522 rate->Stop(); |
| 511 | 523 |
| 512 GarbageCollectionEpilogue(); | 524 GarbageCollectionEpilogue(); |
| 513 } | 525 } |
| 514 | 526 |
| 515 | |
| 516 ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped()); | 527 ASSERT(collector == SCAVENGER || incremental_marking()->IsStopped()); |
| 517 if (incremental_marking()->IsStopped()) { | 528 if (incremental_marking()->IsStopped()) { |
| 518 if (incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull()) { | 529 if (incremental_marking()->WorthActivating() && NextGCIsLikelyToBeFull()) { |
| 519 incremental_marking()->Start(); | 530 incremental_marking()->Start(); |
| 520 } | 531 } |
| 521 } | 532 } |
| 522 | 533 |
| 523 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 524 if (FLAG_log_gc) HeapProfiler::WriteSample(); | |
| 525 #endif | |
| 526 | |
| 527 return next_gc_likely_to_collect_more; | 534 return next_gc_likely_to_collect_more; |
| 528 } | 535 } |
| 529 | 536 |
| 530 | 537 |
| 531 void Heap::PerformScavenge() { | 538 void Heap::PerformScavenge() { |
| 532 GCTracer tracer(this); | 539 GCTracer tracer(this); |
| 533 if (incremental_marking()->IsStopped()) { | 540 if (incremental_marking()->IsStopped()) { |
| 534 PerformGarbageCollection(SCAVENGER, &tracer); | 541 PerformGarbageCollection(SCAVENGER, &tracer); |
| 535 } else { | 542 } else { |
| 536 PerformGarbageCollection(MARK_COMPACTOR, &tracer); | 543 PerformGarbageCollection(MARK_COMPACTOR, &tracer); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 } | 721 } |
| 715 } | 722 } |
| 716 | 723 |
| 717 EnsureFromSpaceIsCommitted(); | 724 EnsureFromSpaceIsCommitted(); |
| 718 | 725 |
| 719 int start_new_space_size = Heap::new_space()->SizeAsInt(); | 726 int start_new_space_size = Heap::new_space()->SizeAsInt(); |
| 720 | 727 |
| 721 if (collector == MARK_COMPACTOR) { | 728 if (collector == MARK_COMPACTOR) { |
| 722 // Perform mark-sweep with optional compaction. | 729 // Perform mark-sweep with optional compaction. |
| 723 MarkCompact(tracer); | 730 MarkCompact(tracer); |
| 724 | 731 sweep_generation_++; |
| 725 bool high_survival_rate_during_scavenges = IsHighSurvivalRate() && | 732 bool high_survival_rate_during_scavenges = IsHighSurvivalRate() && |
| 726 IsStableOrIncreasingSurvivalTrend(); | 733 IsStableOrIncreasingSurvivalTrend(); |
| 727 | 734 |
| 728 UpdateSurvivalRateTrend(start_new_space_size); | 735 UpdateSurvivalRateTrend(start_new_space_size); |
| 729 | 736 |
| 730 intptr_t old_gen_size = PromotedSpaceSize(); | 737 intptr_t old_gen_size = PromotedSpaceSize(); |
| 731 old_gen_promotion_limit_ = | 738 old_gen_promotion_limit_ = |
| 732 old_gen_size + | 739 old_gen_size + |
| 733 Max(kMinimumPromotionLimit, old_gen_size / 3) + | 740 Max(kMinimumPromotionLimit, old_gen_size / 3) + |
| 734 new_space()->Capacity(); | 741 new_space()->Capacity(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 753 } else { | 760 } else { |
| 754 tracer_ = tracer; | 761 tracer_ = tracer; |
| 755 Scavenge(); | 762 Scavenge(); |
| 756 tracer_ = NULL; | 763 tracer_ = NULL; |
| 757 | 764 |
| 758 UpdateSurvivalRateTrend(start_new_space_size); | 765 UpdateSurvivalRateTrend(start_new_space_size); |
| 759 } | 766 } |
| 760 | 767 |
| 761 isolate_->counters()->objs_since_last_young()->Set(0); | 768 isolate_->counters()->objs_since_last_young()->Set(0); |
| 762 | 769 |
| 770 gc_post_processing_depth_++; |
| 763 { DisableAssertNoAllocation allow_allocation; | 771 { DisableAssertNoAllocation allow_allocation; |
| 764 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 772 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
| 765 next_gc_likely_to_collect_more = | 773 next_gc_likely_to_collect_more = |
| 766 isolate_->global_handles()->PostGarbageCollectionProcessing(collector); | 774 isolate_->global_handles()->PostGarbageCollectionProcessing(collector); |
| 767 } | 775 } |
| 776 gc_post_processing_depth_--; |
| 768 | 777 |
| 769 // Update relocatables. | 778 // Update relocatables. |
| 770 Relocatable::PostGarbageCollectionProcessing(); | 779 Relocatable::PostGarbageCollectionProcessing(); |
| 771 | 780 |
| 772 if (collector == MARK_COMPACTOR) { | 781 if (collector == MARK_COMPACTOR) { |
| 773 // Register the amount of external allocated memory. | 782 // Register the amount of external allocated memory. |
| 774 amount_of_external_allocated_memory_at_last_global_gc_ = | 783 amount_of_external_allocated_memory_at_last_global_gc_ = |
| 775 amount_of_external_allocated_memory_; | 784 amount_of_external_allocated_memory_; |
| 776 } | 785 } |
| 777 | 786 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 isolate_->keyed_lookup_cache()->Clear(); | 833 isolate_->keyed_lookup_cache()->Clear(); |
| 825 isolate_->context_slot_cache()->Clear(); | 834 isolate_->context_slot_cache()->Clear(); |
| 826 isolate_->descriptor_lookup_cache()->Clear(); | 835 isolate_->descriptor_lookup_cache()->Clear(); |
| 827 | 836 |
| 828 isolate_->compilation_cache()->MarkCompactPrologue(); | 837 isolate_->compilation_cache()->MarkCompactPrologue(); |
| 829 | 838 |
| 830 CompletelyClearInstanceofCache(); | 839 CompletelyClearInstanceofCache(); |
| 831 | 840 |
| 832 // TODO(gc) select heuristic for flushing NumberString cache with | 841 // TODO(gc) select heuristic for flushing NumberString cache with |
| 833 // FlushNumberStringCache | 842 // FlushNumberStringCache |
| 843 if (FLAG_cleanup_code_caches_at_gc) { |
| 844 polymorphic_code_cache()->set_cache(undefined_value()); |
| 845 } |
| 834 | 846 |
| 835 ClearNormalizedMapCaches(); | 847 ClearNormalizedMapCaches(); |
| 836 } | 848 } |
| 837 | 849 |
| 838 | 850 |
| 839 Object* Heap::FindCodeObject(Address a) { | 851 Object* Heap::FindCodeObject(Address a) { |
| 840 Object* obj = NULL; // Initialization to please compiler. | 852 Object* obj = NULL; // Initialization to please compiler. |
| 841 { MaybeObject* maybe_obj = code_space_->FindObject(a); | 853 { MaybeObject* maybe_obj = code_space_->FindObject(a); |
| 842 if (!maybe_obj->ToObject(&obj)) { | 854 if (!maybe_obj->ToObject(&obj)) { |
| 843 obj = lo_space_->FindObject(a)->ToObjectUnchecked(); | 855 obj = lo_space_->FindObject(a)->ToObjectUnchecked(); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 reinterpret_cast<Address>(cell) + | 1069 reinterpret_cast<Address>(cell) + |
| 1058 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); | 1070 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); |
| 1059 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); | 1071 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); |
| 1060 } | 1072 } |
| 1061 } | 1073 } |
| 1062 | 1074 |
| 1063 // Scavenge object reachable from the global contexts list directly. | 1075 // Scavenge object reachable from the global contexts list directly. |
| 1064 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); | 1076 scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_)); |
| 1065 | 1077 |
| 1066 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1078 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1067 isolate_->global_handles()->IdentifyWeakIndependentHandles( | 1079 isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles( |
| 1068 &IsUnscavengedHeapObject); | 1080 &IsUnscavengedHeapObject); |
| 1069 isolate_->global_handles()->IterateWeakIndependentRoots(&scavenge_visitor); | 1081 isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots( |
| 1082 &scavenge_visitor); |
| 1070 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); | 1083 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); |
| 1071 | 1084 |
| 1072 | 1085 |
| 1073 UpdateNewSpaceReferencesInExternalStringTable( | 1086 UpdateNewSpaceReferencesInExternalStringTable( |
| 1074 &UpdateNewSpaceReferenceInExternalStringTableEntry); | 1087 &UpdateNewSpaceReferenceInExternalStringTableEntry); |
| 1075 | 1088 |
| 1076 LiveObjectList::UpdateReferencesForScavengeGC(); | 1089 LiveObjectList::UpdateReferencesForScavengeGC(); |
| 1077 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); | 1090 isolate()->runtime_profiler()->UpdateSamplesAfterScavenge(); |
| 1078 incremental_marking()->UpdateMarkingDequeAfterScavenge(); | 1091 incremental_marking()->UpdateMarkingDequeAfterScavenge(); |
| 1079 | 1092 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1325 template<MarksHandling marks_handling, | 1338 template<MarksHandling marks_handling, |
| 1326 LoggingAndProfiling logging_and_profiling_mode> | 1339 LoggingAndProfiling logging_and_profiling_mode> |
| 1327 class ScavengingVisitor : public StaticVisitorBase { | 1340 class ScavengingVisitor : public StaticVisitorBase { |
| 1328 public: | 1341 public: |
| 1329 static void Initialize() { | 1342 static void Initialize() { |
| 1330 table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString); | 1343 table_.Register(kVisitSeqAsciiString, &EvacuateSeqAsciiString); |
| 1331 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); | 1344 table_.Register(kVisitSeqTwoByteString, &EvacuateSeqTwoByteString); |
| 1332 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); | 1345 table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate); |
| 1333 table_.Register(kVisitByteArray, &EvacuateByteArray); | 1346 table_.Register(kVisitByteArray, &EvacuateByteArray); |
| 1334 table_.Register(kVisitFixedArray, &EvacuateFixedArray); | 1347 table_.Register(kVisitFixedArray, &EvacuateFixedArray); |
| 1348 table_.Register(kVisitFixedDoubleArray, &EvacuateFixedDoubleArray); |
| 1335 | 1349 |
| 1336 table_.Register(kVisitGlobalContext, | 1350 table_.Register(kVisitGlobalContext, |
| 1337 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1351 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1338 template VisitSpecialized<Context::kSize>); | 1352 template VisitSpecialized<Context::kSize>); |
| 1339 | 1353 |
| 1340 table_.Register(kVisitConsString, | 1354 table_.Register(kVisitConsString, |
| 1341 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1355 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1342 template VisitSpecialized<ConsString::kSize>); | 1356 template VisitSpecialized<ConsString::kSize>); |
| 1343 | 1357 |
| 1344 table_.Register(kVisitSharedFunctionInfo, | 1358 table_.Register(kVisitSharedFunctionInfo, |
| 1345 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1359 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1346 template VisitSpecialized<SharedFunctionInfo::kSize>); | 1360 template VisitSpecialized<SharedFunctionInfo::kSize>); |
| 1347 | 1361 |
| 1362 table_.Register(kVisitJSRegExp, |
| 1363 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1364 Visit); |
| 1365 |
| 1348 table_.Register(kVisitJSFunction, | 1366 table_.Register(kVisitJSFunction, |
| 1349 &ObjectEvacuationStrategy<POINTER_OBJECT>:: | 1367 &ObjectEvacuationStrategy<POINTER_OBJECT>:: |
| 1350 template VisitSpecialized<JSFunction::kSize>); | 1368 template VisitSpecialized<JSFunction::kSize>); |
| 1351 | 1369 |
| 1352 table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>, | 1370 table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>, |
| 1353 kVisitDataObject, | 1371 kVisitDataObject, |
| 1354 kVisitDataObjectGeneric>(); | 1372 kVisitDataObjectGeneric>(); |
| 1355 | 1373 |
| 1356 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, | 1374 table_.RegisterSpecializations<ObjectEvacuationStrategy<POINTER_OBJECT>, |
| 1357 kVisitJSObject, | 1375 kVisitJSObject, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1482 HeapObject** slot, | 1500 HeapObject** slot, |
| 1483 HeapObject* object) { | 1501 HeapObject* object) { |
| 1484 int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); | 1502 int object_size = FixedArray::BodyDescriptor::SizeOf(map, object); |
| 1485 EvacuateObject<POINTER_OBJECT, UNKNOWN_SIZE>(map, | 1503 EvacuateObject<POINTER_OBJECT, UNKNOWN_SIZE>(map, |
| 1486 slot, | 1504 slot, |
| 1487 object, | 1505 object, |
| 1488 object_size); | 1506 object_size); |
| 1489 } | 1507 } |
| 1490 | 1508 |
| 1491 | 1509 |
| 1510 static inline void EvacuateFixedDoubleArray(Map* map, |
| 1511 HeapObject** slot, |
| 1512 HeapObject* object) { |
| 1513 int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); |
| 1514 int object_size = FixedDoubleArray::SizeFor(length); |
| 1515 EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, |
| 1516 slot, |
| 1517 object, |
| 1518 object_size); |
| 1519 } |
| 1520 |
| 1521 |
| 1492 static inline void EvacuateByteArray(Map* map, | 1522 static inline void EvacuateByteArray(Map* map, |
| 1493 HeapObject** slot, | 1523 HeapObject** slot, |
| 1494 HeapObject* object) { | 1524 HeapObject* object) { |
| 1495 int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); | 1525 int object_size = reinterpret_cast<ByteArray*>(object)->ByteArraySize(); |
| 1496 EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size); | 1526 EvacuateObject<DATA_OBJECT, UNKNOWN_SIZE>(map, slot, object, object_size); |
| 1497 } | 1527 } |
| 1498 | 1528 |
| 1499 | 1529 |
| 1500 static inline void EvacuateSeqAsciiString(Map* map, | 1530 static inline void EvacuateSeqAsciiString(Map* map, |
| 1501 HeapObject** slot, | 1531 HeapObject** slot, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1599 #ifdef ENABLE_LOGGING_AND_PROFILING | 1629 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 1600 bool logging_and_profiling = | 1630 bool logging_and_profiling = |
| 1601 isolate()->logger()->is_logging() || | 1631 isolate()->logger()->is_logging() || |
| 1602 CpuProfiler::is_profiling(isolate()) || | 1632 CpuProfiler::is_profiling(isolate()) || |
| 1603 (isolate()->heap_profiler() != NULL && | 1633 (isolate()->heap_profiler() != NULL && |
| 1604 isolate()->heap_profiler()->is_profiling()); | 1634 isolate()->heap_profiler()->is_profiling()); |
| 1605 #else | 1635 #else |
| 1606 bool logging_and_profiling = false; | 1636 bool logging_and_profiling = false; |
| 1607 #endif | 1637 #endif |
| 1608 | 1638 |
| 1609 | |
| 1610 if (!incremental_marking()->IsMarking()) { | 1639 if (!incremental_marking()->IsMarking()) { |
| 1611 if (!logging_and_profiling) { | 1640 if (!logging_and_profiling) { |
| 1612 scavenging_visitors_table_.CopyFrom( | 1641 scavenging_visitors_table_.CopyFrom( |
| 1613 ScavengingVisitor<IGNORE_MARKS, | 1642 ScavengingVisitor<IGNORE_MARKS, |
| 1614 LOGGING_AND_PROFILING_DISABLED>::GetTable()); | 1643 LOGGING_AND_PROFILING_DISABLED>::GetTable()); |
| 1615 } else { | 1644 } else { |
| 1616 scavenging_visitors_table_.CopyFrom( | 1645 scavenging_visitors_table_.CopyFrom( |
| 1617 ScavengingVisitor<IGNORE_MARKS, | 1646 ScavengingVisitor<IGNORE_MARKS, |
| 1618 LOGGING_AND_PROFILING_ENABLED>::GetTable()); | 1647 LOGGING_AND_PROFILING_ENABLED>::GetTable()); |
| 1619 } | 1648 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1676 map->set_prototype(null_value()); | 1705 map->set_prototype(null_value()); |
| 1677 map->set_constructor(null_value()); | 1706 map->set_constructor(null_value()); |
| 1678 map->set_instance_size(instance_size); | 1707 map->set_instance_size(instance_size); |
| 1679 map->set_inobject_properties(0); | 1708 map->set_inobject_properties(0); |
| 1680 map->set_pre_allocated_property_fields(0); | 1709 map->set_pre_allocated_property_fields(0); |
| 1681 map->init_instance_descriptors(); | 1710 map->init_instance_descriptors(); |
| 1682 map->set_code_cache(empty_fixed_array()); | 1711 map->set_code_cache(empty_fixed_array()); |
| 1683 map->set_prototype_transitions(empty_fixed_array()); | 1712 map->set_prototype_transitions(empty_fixed_array()); |
| 1684 map->set_unused_property_fields(0); | 1713 map->set_unused_property_fields(0); |
| 1685 map->set_bit_field(0); | 1714 map->set_bit_field(0); |
| 1686 map->set_bit_field2((1 << Map::kIsExtensible) | (1 << Map::kHasFastElements)); | 1715 map->set_bit_field2(1 << Map::kIsExtensible); |
| 1716 map->set_elements_kind(JSObject::FAST_ELEMENTS); |
| 1687 | 1717 |
| 1688 // If the map object is aligned fill the padding area with Smi 0 objects. | 1718 // If the map object is aligned fill the padding area with Smi 0 objects. |
| 1689 if (Map::kPadStart < Map::kSize) { | 1719 if (Map::kPadStart < Map::kSize) { |
| 1690 memset(reinterpret_cast<byte*>(map) + Map::kPadStart - kHeapObjectTag, | 1720 memset(reinterpret_cast<byte*>(map) + Map::kPadStart - kHeapObjectTag, |
| 1691 0, | 1721 0, |
| 1692 Map::kSize - Map::kPadStart); | 1722 Map::kSize - Map::kPadStart); |
| 1693 } | 1723 } |
| 1694 return map; | 1724 return map; |
| 1695 } | 1725 } |
| 1696 | 1726 |
| 1697 | 1727 |
| 1698 MaybeObject* Heap::AllocateCodeCache() { | 1728 MaybeObject* Heap::AllocateCodeCache() { |
| 1699 Object* result; | 1729 Object* result; |
| 1700 { MaybeObject* maybe_result = AllocateStruct(CODE_CACHE_TYPE); | 1730 { MaybeObject* maybe_result = AllocateStruct(CODE_CACHE_TYPE); |
| 1701 if (!maybe_result->ToObject(&result)) return maybe_result; | 1731 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1702 } | 1732 } |
| 1703 CodeCache* code_cache = CodeCache::cast(result); | 1733 CodeCache* code_cache = CodeCache::cast(result); |
| 1704 code_cache->set_default_cache(empty_fixed_array()); | 1734 code_cache->set_default_cache(empty_fixed_array()); |
| 1705 code_cache->set_normal_type_cache(undefined_value()); | 1735 code_cache->set_normal_type_cache(undefined_value()); |
| 1706 return code_cache; | 1736 return code_cache; |
| 1707 } | 1737 } |
| 1708 | 1738 |
| 1709 | 1739 |
| 1740 MaybeObject* Heap::AllocatePolymorphicCodeCache() { |
| 1741 return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE); |
| 1742 } |
| 1743 |
| 1744 |
| 1710 const Heap::StringTypeTable Heap::string_type_table[] = { | 1745 const Heap::StringTypeTable Heap::string_type_table[] = { |
| 1711 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ | 1746 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ |
| 1712 {type, size, k##camel_name##MapRootIndex}, | 1747 {type, size, k##camel_name##MapRootIndex}, |
| 1713 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) | 1748 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) |
| 1714 #undef STRING_TYPE_ELEMENT | 1749 #undef STRING_TYPE_ELEMENT |
| 1715 }; | 1750 }; |
| 1716 | 1751 |
| 1717 | 1752 |
| 1718 const Heap::ConstantSymbolTable Heap::constant_symbol_table[] = { | 1753 const Heap::ConstantSymbolTable Heap::constant_symbol_table[] = { |
| 1719 #define CONSTANT_SYMBOL_ELEMENT(name, contents) \ | 1754 #define CONSTANT_SYMBOL_ELEMENT(name, contents) \ |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1825 Map::cast(obj)->set_is_undetectable(); | 1860 Map::cast(obj)->set_is_undetectable(); |
| 1826 | 1861 |
| 1827 { MaybeObject* maybe_obj = | 1862 { MaybeObject* maybe_obj = |
| 1828 AllocateMap(ASCII_STRING_TYPE, kVariableSizeSentinel); | 1863 AllocateMap(ASCII_STRING_TYPE, kVariableSizeSentinel); |
| 1829 if (!maybe_obj->ToObject(&obj)) return false; | 1864 if (!maybe_obj->ToObject(&obj)) return false; |
| 1830 } | 1865 } |
| 1831 set_undetectable_ascii_string_map(Map::cast(obj)); | 1866 set_undetectable_ascii_string_map(Map::cast(obj)); |
| 1832 Map::cast(obj)->set_is_undetectable(); | 1867 Map::cast(obj)->set_is_undetectable(); |
| 1833 | 1868 |
| 1834 { MaybeObject* maybe_obj = | 1869 { MaybeObject* maybe_obj = |
| 1870 AllocateMap(FIXED_DOUBLE_ARRAY_TYPE, kVariableSizeSentinel); |
| 1871 if (!maybe_obj->ToObject(&obj)) return false; |
| 1872 } |
| 1873 set_fixed_double_array_map(Map::cast(obj)); |
| 1874 |
| 1875 { MaybeObject* maybe_obj = |
| 1835 AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel); | 1876 AllocateMap(BYTE_ARRAY_TYPE, kVariableSizeSentinel); |
| 1836 if (!maybe_obj->ToObject(&obj)) return false; | 1877 if (!maybe_obj->ToObject(&obj)) return false; |
| 1837 } | 1878 } |
| 1838 set_byte_array_map(Map::cast(obj)); | 1879 set_byte_array_map(Map::cast(obj)); |
| 1839 | 1880 |
| 1840 { MaybeObject* maybe_obj = | 1881 { MaybeObject* maybe_obj = |
| 1841 AllocateMap(FREE_SPACE_TYPE, kVariableSizeSentinel); | 1882 AllocateMap(FREE_SPACE_TYPE, kVariableSizeSentinel); |
| 1842 if (!maybe_obj->ToObject(&obj)) return false; | 1883 if (!maybe_obj->ToObject(&obj)) return false; |
| 1843 } | 1884 } |
| 1844 set_free_space_map(Map::cast(obj)); | 1885 set_free_space_map(Map::cast(obj)); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1889 if (!maybe_obj->ToObject(&obj)) return false; | 1930 if (!maybe_obj->ToObject(&obj)) return false; |
| 1890 } | 1931 } |
| 1891 set_external_unsigned_int_array_map(Map::cast(obj)); | 1932 set_external_unsigned_int_array_map(Map::cast(obj)); |
| 1892 | 1933 |
| 1893 { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_FLOAT_ARRAY_TYPE, | 1934 { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_FLOAT_ARRAY_TYPE, |
| 1894 ExternalArray::kAlignedSize); | 1935 ExternalArray::kAlignedSize); |
| 1895 if (!maybe_obj->ToObject(&obj)) return false; | 1936 if (!maybe_obj->ToObject(&obj)) return false; |
| 1896 } | 1937 } |
| 1897 set_external_float_array_map(Map::cast(obj)); | 1938 set_external_float_array_map(Map::cast(obj)); |
| 1898 | 1939 |
| 1940 { MaybeObject* maybe_obj = |
| 1941 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); |
| 1942 if (!maybe_obj->ToObject(&obj)) return false; |
| 1943 } |
| 1944 set_non_strict_arguments_elements_map(Map::cast(obj)); |
| 1945 |
| 1899 { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_DOUBLE_ARRAY_TYPE, | 1946 { MaybeObject* maybe_obj = AllocateMap(EXTERNAL_DOUBLE_ARRAY_TYPE, |
| 1900 ExternalArray::kAlignedSize); | 1947 ExternalArray::kAlignedSize); |
| 1901 if (!maybe_obj->ToObject(&obj)) return false; | 1948 if (!maybe_obj->ToObject(&obj)) return false; |
| 1902 } | 1949 } |
| 1903 set_external_double_array_map(Map::cast(obj)); | 1950 set_external_double_array_map(Map::cast(obj)); |
| 1904 | 1951 |
| 1905 { MaybeObject* maybe_obj = AllocateMap(CODE_TYPE, kVariableSizeSentinel); | 1952 { MaybeObject* maybe_obj = AllocateMap(CODE_TYPE, kVariableSizeSentinel); |
| 1906 if (!maybe_obj->ToObject(&obj)) return false; | 1953 if (!maybe_obj->ToObject(&obj)) return false; |
| 1907 } | 1954 } |
| 1908 set_code_map(Map::cast(obj)); | 1955 set_code_map(Map::cast(obj)); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1934 { MaybeObject* maybe_obj = | 1981 { MaybeObject* maybe_obj = |
| 1935 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); | 1982 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); |
| 1936 if (!maybe_obj->ToObject(&obj)) return false; | 1983 if (!maybe_obj->ToObject(&obj)) return false; |
| 1937 } | 1984 } |
| 1938 set_hash_table_map(Map::cast(obj)); | 1985 set_hash_table_map(Map::cast(obj)); |
| 1939 | 1986 |
| 1940 { MaybeObject* maybe_obj = | 1987 { MaybeObject* maybe_obj = |
| 1941 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); | 1988 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); |
| 1942 if (!maybe_obj->ToObject(&obj)) return false; | 1989 if (!maybe_obj->ToObject(&obj)) return false; |
| 1943 } | 1990 } |
| 1944 set_context_map(Map::cast(obj)); | 1991 set_function_context_map(Map::cast(obj)); |
| 1945 | 1992 |
| 1946 { MaybeObject* maybe_obj = | 1993 { MaybeObject* maybe_obj = |
| 1947 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); | 1994 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); |
| 1948 if (!maybe_obj->ToObject(&obj)) return false; | 1995 if (!maybe_obj->ToObject(&obj)) return false; |
| 1949 } | 1996 } |
| 1950 set_catch_context_map(Map::cast(obj)); | 1997 set_catch_context_map(Map::cast(obj)); |
| 1951 | 1998 |
| 1952 { MaybeObject* maybe_obj = | 1999 { MaybeObject* maybe_obj = |
| 1953 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); | 2000 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); |
| 1954 if (!maybe_obj->ToObject(&obj)) return false; | 2001 if (!maybe_obj->ToObject(&obj)) return false; |
| 1955 } | 2002 } |
| 2003 set_with_context_map(Map::cast(obj)); |
| 2004 |
| 2005 { MaybeObject* maybe_obj = |
| 2006 AllocateMap(FIXED_ARRAY_TYPE, kVariableSizeSentinel); |
| 2007 if (!maybe_obj->ToObject(&obj)) return false; |
| 2008 } |
| 1956 Map* global_context_map = Map::cast(obj); | 2009 Map* global_context_map = Map::cast(obj); |
| 1957 global_context_map->set_visitor_id(StaticVisitorBase::kVisitGlobalContext); | 2010 global_context_map->set_visitor_id(StaticVisitorBase::kVisitGlobalContext); |
| 1958 set_global_context_map(global_context_map); | 2011 set_global_context_map(global_context_map); |
| 1959 | 2012 |
| 1960 { MaybeObject* maybe_obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE, | 2013 { MaybeObject* maybe_obj = AllocateMap(SHARED_FUNCTION_INFO_TYPE, |
| 1961 SharedFunctionInfo::kAlignedSize); | 2014 SharedFunctionInfo::kAlignedSize); |
| 1962 if (!maybe_obj->ToObject(&obj)) return false; | 2015 if (!maybe_obj->ToObject(&obj)) return false; |
| 1963 } | 2016 } |
| 1964 set_shared_function_info_map(Map::cast(obj)); | 2017 set_shared_function_info_map(Map::cast(obj)); |
| 1965 | 2018 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2213 } | 2266 } |
| 2214 set_code_stubs(NumberDictionary::cast(obj)); | 2267 set_code_stubs(NumberDictionary::cast(obj)); |
| 2215 | 2268 |
| 2216 // Allocate the non_monomorphic_cache used in stub-cache.cc. The initial size | 2269 // Allocate the non_monomorphic_cache used in stub-cache.cc. The initial size |
| 2217 // is set to avoid expanding the dictionary during bootstrapping. | 2270 // is set to avoid expanding the dictionary during bootstrapping. |
| 2218 { MaybeObject* maybe_obj = NumberDictionary::Allocate(64); | 2271 { MaybeObject* maybe_obj = NumberDictionary::Allocate(64); |
| 2219 if (!maybe_obj->ToObject(&obj)) return false; | 2272 if (!maybe_obj->ToObject(&obj)) return false; |
| 2220 } | 2273 } |
| 2221 set_non_monomorphic_cache(NumberDictionary::cast(obj)); | 2274 set_non_monomorphic_cache(NumberDictionary::cast(obj)); |
| 2222 | 2275 |
| 2276 { MaybeObject* maybe_obj = AllocatePolymorphicCodeCache(); |
| 2277 if (!maybe_obj->ToObject(&obj)) return false; |
| 2278 } |
| 2279 set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj)); |
| 2280 |
| 2223 set_instanceof_cache_function(Smi::FromInt(0)); | 2281 set_instanceof_cache_function(Smi::FromInt(0)); |
| 2224 set_instanceof_cache_map(Smi::FromInt(0)); | 2282 set_instanceof_cache_map(Smi::FromInt(0)); |
| 2225 set_instanceof_cache_answer(Smi::FromInt(0)); | 2283 set_instanceof_cache_answer(Smi::FromInt(0)); |
| 2226 | 2284 |
| 2227 CreateFixedStubs(); | 2285 CreateFixedStubs(); |
| 2228 | 2286 |
| 2229 // Allocate the dictionary of intrinsic function names. | 2287 // Allocate the dictionary of intrinsic function names. |
| 2230 { MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions); | 2288 { MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions); |
| 2231 if (!maybe_obj->ToObject(&obj)) return false; | 2289 if (!maybe_obj->ToObject(&obj)) return false; |
| 2232 } | 2290 } |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2462 share->set_inferred_name(empty_string()); | 2520 share->set_inferred_name(empty_string()); |
| 2463 share->set_compiler_hints(0); | 2521 share->set_compiler_hints(0); |
| 2464 share->set_deopt_counter(Smi::FromInt(FLAG_deopt_every_n_times)); | 2522 share->set_deopt_counter(Smi::FromInt(FLAG_deopt_every_n_times)); |
| 2465 share->set_initial_map(undefined_value()); | 2523 share->set_initial_map(undefined_value()); |
| 2466 share->set_this_property_assignments_count(0); | 2524 share->set_this_property_assignments_count(0); |
| 2467 share->set_this_property_assignments(undefined_value()); | 2525 share->set_this_property_assignments(undefined_value()); |
| 2468 share->set_opt_count(0); | 2526 share->set_opt_count(0); |
| 2469 share->set_num_literals(0); | 2527 share->set_num_literals(0); |
| 2470 share->set_end_position(0); | 2528 share->set_end_position(0); |
| 2471 share->set_function_token_position(0); | 2529 share->set_function_token_position(0); |
| 2472 share->set_es5_native(false); | 2530 share->set_native(false); |
| 2473 return result; | 2531 return result; |
| 2474 } | 2532 } |
| 2475 | 2533 |
| 2476 | 2534 |
| 2477 MaybeObject* Heap::AllocateJSMessageObject(String* type, | 2535 MaybeObject* Heap::AllocateJSMessageObject(String* type, |
| 2478 JSArray* arguments, | 2536 JSArray* arguments, |
| 2479 int start_position, | 2537 int start_position, |
| 2480 int end_position, | 2538 int end_position, |
| 2481 Object* script, | 2539 Object* script, |
| 2482 Object* stack_trace, | 2540 Object* stack_trace, |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2653 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc); | 2711 WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc); |
| 2654 cons_string->set_length(length); | 2712 cons_string->set_length(length); |
| 2655 cons_string->set_hash_field(String::kEmptyHashField); | 2713 cons_string->set_hash_field(String::kEmptyHashField); |
| 2656 cons_string->set_first(first, mode); | 2714 cons_string->set_first(first, mode); |
| 2657 cons_string->set_second(second, mode); | 2715 cons_string->set_second(second, mode); |
| 2658 return result; | 2716 return result; |
| 2659 } | 2717 } |
| 2660 | 2718 |
| 2661 | 2719 |
| 2662 MaybeObject* Heap::AllocateSubString(String* buffer, | 2720 MaybeObject* Heap::AllocateSubString(String* buffer, |
| 2663 int start, | 2721 int start, |
| 2664 int end, | 2722 int end, |
| 2665 PretenureFlag pretenure) { | 2723 PretenureFlag pretenure) { |
| 2666 int length = end - start; | 2724 int length = end - start; |
| 2667 | 2725 if (length == 0) { |
| 2668 if (length == 1) { | 2726 return empty_string(); |
| 2727 } else if (length == 1) { |
| 2669 return LookupSingleCharacterStringFromCode(buffer->Get(start)); | 2728 return LookupSingleCharacterStringFromCode(buffer->Get(start)); |
| 2670 } else if (length == 2) { | 2729 } else if (length == 2) { |
| 2671 // Optimization for 2-byte strings often used as keys in a decompression | 2730 // Optimization for 2-byte strings often used as keys in a decompression |
| 2672 // dictionary. Check whether we already have the string in the symbol | 2731 // dictionary. Check whether we already have the string in the symbol |
| 2673 // table to prevent creation of many unneccesary strings. | 2732 // table to prevent creation of many unneccesary strings. |
| 2674 unsigned c1 = buffer->Get(start); | 2733 unsigned c1 = buffer->Get(start); |
| 2675 unsigned c2 = buffer->Get(start + 1); | 2734 unsigned c2 = buffer->Get(start + 1); |
| 2676 return MakeOrFindTwoCharacterString(this, c1, c2); | 2735 return MakeOrFindTwoCharacterString(this, c1, c2); |
| 2677 } | 2736 } |
| 2678 | 2737 |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2998 // If allocation failures are disallowed, we may allocate in a different | 3057 // If allocation failures are disallowed, we may allocate in a different |
| 2999 // space when new space is full and the object is not a large object. | 3058 // space when new space is full and the object is not a large object. |
| 3000 AllocationSpace retry_space = | 3059 AllocationSpace retry_space = |
| 3001 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); | 3060 (space != NEW_SPACE) ? space : TargetSpaceId(map->instance_type()); |
| 3002 Object* result; | 3061 Object* result; |
| 3003 { MaybeObject* maybe_result = | 3062 { MaybeObject* maybe_result = |
| 3004 AllocateRaw(map->instance_size(), space, retry_space); | 3063 AllocateRaw(map->instance_size(), space, retry_space); |
| 3005 if (!maybe_result->ToObject(&result)) return maybe_result; | 3064 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3006 } | 3065 } |
| 3007 HeapObject::cast(result)->set_map(map); | 3066 HeapObject::cast(result)->set_map(map); |
| 3008 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 3009 isolate_->producer_heap_profile()->RecordJSObjectAllocation(result); | |
| 3010 #endif | |
| 3011 return result; | 3067 return result; |
| 3012 } | 3068 } |
| 3013 | 3069 |
| 3014 | 3070 |
| 3015 MaybeObject* Heap::InitializeFunction(JSFunction* function, | 3071 MaybeObject* Heap::InitializeFunction(JSFunction* function, |
| 3016 SharedFunctionInfo* shared, | 3072 SharedFunctionInfo* shared, |
| 3017 Object* prototype) { | 3073 Object* prototype) { |
| 3018 ASSERT(!prototype->IsMap()); | 3074 ASSERT(!prototype->IsMap()); |
| 3019 function->initialize_properties(); | 3075 function->initialize_properties(); |
| 3020 function->initialize_elements(); | 3076 function->initialize_elements(); |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3449 } | 3505 } |
| 3450 // Update properties if necessary. | 3506 // Update properties if necessary. |
| 3451 if (properties->length() > 0) { | 3507 if (properties->length() > 0) { |
| 3452 Object* prop; | 3508 Object* prop; |
| 3453 { MaybeObject* maybe_prop = CopyFixedArray(properties); | 3509 { MaybeObject* maybe_prop = CopyFixedArray(properties); |
| 3454 if (!maybe_prop->ToObject(&prop)) return maybe_prop; | 3510 if (!maybe_prop->ToObject(&prop)) return maybe_prop; |
| 3455 } | 3511 } |
| 3456 JSObject::cast(clone)->set_properties(FixedArray::cast(prop)); | 3512 JSObject::cast(clone)->set_properties(FixedArray::cast(prop)); |
| 3457 } | 3513 } |
| 3458 // Return the new clone. | 3514 // Return the new clone. |
| 3459 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 3460 isolate_->producer_heap_profile()->RecordJSObjectAllocation(clone); | |
| 3461 #endif | |
| 3462 return clone; | 3515 return clone; |
| 3463 } | 3516 } |
| 3464 | 3517 |
| 3465 | 3518 |
| 3466 MaybeObject* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor, | 3519 MaybeObject* Heap::ReinitializeJSGlobalProxy(JSFunction* constructor, |
| 3467 JSGlobalProxy* object) { | 3520 JSGlobalProxy* object) { |
| 3468 ASSERT(constructor->has_initial_map()); | 3521 ASSERT(constructor->has_initial_map()); |
| 3469 Map* map = constructor->initial_map(); | 3522 Map* map = constructor->initial_map(); |
| 3470 | 3523 |
| 3471 // Check that the already allocated object has the same size and type as | 3524 // Check that the already allocated object has the same size and type as |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3866 { MaybeObject* maybe_obj = AllocateRawFixedArray(length); | 3919 { MaybeObject* maybe_obj = AllocateRawFixedArray(length); |
| 3867 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3920 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3868 } | 3921 } |
| 3869 | 3922 |
| 3870 reinterpret_cast<FixedArray*>(obj)->set_map(fixed_array_map()); | 3923 reinterpret_cast<FixedArray*>(obj)->set_map(fixed_array_map()); |
| 3871 FixedArray::cast(obj)->set_length(length); | 3924 FixedArray::cast(obj)->set_length(length); |
| 3872 return obj; | 3925 return obj; |
| 3873 } | 3926 } |
| 3874 | 3927 |
| 3875 | 3928 |
| 3929 MaybeObject* Heap::AllocateEmptyFixedDoubleArray() { |
| 3930 int size = FixedDoubleArray::SizeFor(0); |
| 3931 Object* result; |
| 3932 { MaybeObject* maybe_result = |
| 3933 AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE); |
| 3934 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3935 } |
| 3936 // Initialize the object. |
| 3937 reinterpret_cast<FixedDoubleArray*>(result)->set_map( |
| 3938 fixed_double_array_map()); |
| 3939 reinterpret_cast<FixedDoubleArray*>(result)->set_length(0); |
| 3940 return result; |
| 3941 } |
| 3942 |
| 3943 |
| 3944 MaybeObject* Heap::AllocateUninitializedFixedDoubleArray( |
| 3945 int length, |
| 3946 PretenureFlag pretenure) { |
| 3947 if (length == 0) return empty_fixed_double_array(); |
| 3948 |
| 3949 Object* obj; |
| 3950 { MaybeObject* maybe_obj = AllocateRawFixedDoubleArray(length, pretenure); |
| 3951 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3952 } |
| 3953 |
| 3954 reinterpret_cast<FixedDoubleArray*>(obj)->set_map(fixed_double_array_map()); |
| 3955 FixedDoubleArray::cast(obj)->set_length(length); |
| 3956 return obj; |
| 3957 } |
| 3958 |
| 3959 |
| 3960 MaybeObject* Heap::AllocateRawFixedDoubleArray(int length, |
| 3961 PretenureFlag pretenure) { |
| 3962 if (length < 0 || length > FixedDoubleArray::kMaxLength) { |
| 3963 return Failure::OutOfMemoryException(); |
| 3964 } |
| 3965 |
| 3966 AllocationSpace space = |
| 3967 (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE; |
| 3968 int size = FixedDoubleArray::SizeFor(length); |
| 3969 if (space == NEW_SPACE && size > kMaxObjectSizeInNewSpace) { |
| 3970 // Too big for new space. |
| 3971 space = LO_SPACE; |
| 3972 } else if (space == OLD_DATA_SPACE && |
| 3973 size > MaxObjectSizeInPagedSpace()) { |
| 3974 // Too big for old data space. |
| 3975 space = LO_SPACE; |
| 3976 } |
| 3977 |
| 3978 AllocationSpace retry_space = |
| 3979 (size <= MaxObjectSizeInPagedSpace()) ? OLD_DATA_SPACE : LO_SPACE; |
| 3980 |
| 3981 return AllocateRaw(size, space, retry_space); |
| 3982 } |
| 3983 |
| 3984 |
| 3876 MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { | 3985 MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) { |
| 3877 Object* result; | 3986 Object* result; |
| 3878 { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure); | 3987 { MaybeObject* maybe_result = AllocateFixedArray(length, pretenure); |
| 3879 if (!maybe_result->ToObject(&result)) return maybe_result; | 3988 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3880 } | 3989 } |
| 3881 reinterpret_cast<HeapObject*>(result)->set_map(hash_table_map()); | 3990 reinterpret_cast<HeapObject*>(result)->set_map(hash_table_map()); |
| 3882 ASSERT(result->IsHashTable()); | 3991 ASSERT(result->IsHashTable()); |
| 3883 return result; | 3992 return result; |
| 3884 } | 3993 } |
| 3885 | 3994 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3898 } | 4007 } |
| 3899 | 4008 |
| 3900 | 4009 |
| 3901 MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) { | 4010 MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) { |
| 3902 ASSERT(length >= Context::MIN_CONTEXT_SLOTS); | 4011 ASSERT(length >= Context::MIN_CONTEXT_SLOTS); |
| 3903 Object* result; | 4012 Object* result; |
| 3904 { MaybeObject* maybe_result = AllocateFixedArray(length); | 4013 { MaybeObject* maybe_result = AllocateFixedArray(length); |
| 3905 if (!maybe_result->ToObject(&result)) return maybe_result; | 4014 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3906 } | 4015 } |
| 3907 Context* context = reinterpret_cast<Context*>(result); | 4016 Context* context = reinterpret_cast<Context*>(result); |
| 3908 context->set_map(context_map()); | 4017 context->set_map(function_context_map()); |
| 3909 context->set_closure(function); | 4018 context->set_closure(function); |
| 3910 context->set_fcontext(context); | 4019 context->set_previous(function->context()); |
| 3911 context->set_previous(NULL); | |
| 3912 context->set_extension(NULL); | 4020 context->set_extension(NULL); |
| 3913 context->set_global(function->context()->global()); | 4021 context->set_global(function->context()->global()); |
| 3914 ASSERT(!context->IsGlobalContext()); | 4022 return context; |
| 3915 ASSERT(context->is_function_context()); | |
| 3916 ASSERT(result->IsContext()); | |
| 3917 return result; | |
| 3918 } | 4023 } |
| 3919 | 4024 |
| 3920 | 4025 |
| 3921 MaybeObject* Heap::AllocateWithContext(Context* previous, | 4026 MaybeObject* Heap::AllocateCatchContext(JSFunction* function, |
| 3922 JSObject* extension, | 4027 Context* previous, |
| 3923 bool is_catch_context) { | 4028 String* name, |
| 4029 Object* thrown_object) { |
| 4030 STATIC_ASSERT(Context::MIN_CONTEXT_SLOTS == Context::THROWN_OBJECT_INDEX); |
| 4031 Object* result; |
| 4032 { MaybeObject* maybe_result = |
| 4033 AllocateFixedArray(Context::MIN_CONTEXT_SLOTS + 1); |
| 4034 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4035 } |
| 4036 Context* context = reinterpret_cast<Context*>(result); |
| 4037 context->set_map(catch_context_map()); |
| 4038 context->set_closure(function); |
| 4039 context->set_previous(previous); |
| 4040 context->set_extension(name); |
| 4041 context->set_global(previous->global()); |
| 4042 context->set(Context::THROWN_OBJECT_INDEX, thrown_object); |
| 4043 return context; |
| 4044 } |
| 4045 |
| 4046 |
| 4047 MaybeObject* Heap::AllocateWithContext(JSFunction* function, |
| 4048 Context* previous, |
| 4049 JSObject* extension) { |
| 3924 Object* result; | 4050 Object* result; |
| 3925 { MaybeObject* maybe_result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS); | 4051 { MaybeObject* maybe_result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS); |
| 3926 if (!maybe_result->ToObject(&result)) return maybe_result; | 4052 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3927 } | 4053 } |
| 3928 Context* context = reinterpret_cast<Context*>(result); | 4054 Context* context = reinterpret_cast<Context*>(result); |
| 3929 context->set_map(is_catch_context ? catch_context_map() : | 4055 context->set_map(with_context_map()); |
| 3930 context_map()); | 4056 context->set_closure(function); |
| 3931 context->set_closure(previous->closure()); | |
| 3932 context->set_fcontext(previous->fcontext()); | |
| 3933 context->set_previous(previous); | 4057 context->set_previous(previous); |
| 3934 context->set_extension(extension); | 4058 context->set_extension(extension); |
| 3935 context->set_global(previous->global()); | 4059 context->set_global(previous->global()); |
| 3936 ASSERT(!context->IsGlobalContext()); | 4060 return context; |
| 3937 ASSERT(!context->is_function_context()); | |
| 3938 ASSERT(result->IsContext()); | |
| 3939 return result; | |
| 3940 } | 4061 } |
| 3941 | 4062 |
| 3942 | 4063 |
| 3943 MaybeObject* Heap::AllocateStruct(InstanceType type) { | 4064 MaybeObject* Heap::AllocateStruct(InstanceType type) { |
| 3944 Map* map; | 4065 Map* map; |
| 3945 switch (type) { | 4066 switch (type) { |
| 3946 #define MAKE_CASE(NAME, Name, name) \ | 4067 #define MAKE_CASE(NAME, Name, name) \ |
| 3947 case NAME##_TYPE: map = name##_map(); break; | 4068 case NAME##_TYPE: map = name##_map(); break; |
| 3948 STRUCT_LIST(MAKE_CASE) | 4069 STRUCT_LIST(MAKE_CASE) |
| 3949 #undef MAKE_CASE | 4070 #undef MAKE_CASE |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4511 | 4632 |
| 4512 isolate_->bootstrapper()->Iterate(v); | 4633 isolate_->bootstrapper()->Iterate(v); |
| 4513 v->Synchronize("bootstrapper"); | 4634 v->Synchronize("bootstrapper"); |
| 4514 isolate_->Iterate(v); | 4635 isolate_->Iterate(v); |
| 4515 v->Synchronize("top"); | 4636 v->Synchronize("top"); |
| 4516 Relocatable::Iterate(v); | 4637 Relocatable::Iterate(v); |
| 4517 v->Synchronize("relocatable"); | 4638 v->Synchronize("relocatable"); |
| 4518 | 4639 |
| 4519 #ifdef ENABLE_DEBUGGER_SUPPORT | 4640 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 4520 isolate_->debug()->Iterate(v); | 4641 isolate_->debug()->Iterate(v); |
| 4642 if (isolate_->deoptimizer_data() != NULL) { |
| 4643 isolate_->deoptimizer_data()->Iterate(v); |
| 4644 } |
| 4521 #endif | 4645 #endif |
| 4522 v->Synchronize("debug"); | 4646 v->Synchronize("debug"); |
| 4523 isolate_->compilation_cache()->Iterate(v); | 4647 isolate_->compilation_cache()->Iterate(v); |
| 4524 v->Synchronize("compilationcache"); | 4648 v->Synchronize("compilationcache"); |
| 4525 | 4649 |
| 4526 // Iterate over local handles in handle scopes. | 4650 // Iterate over local handles in handle scopes. |
| 4527 isolate_->handle_scope_implementer()->Iterate(v); | 4651 isolate_->handle_scope_implementer()->Iterate(v); |
| 4528 v->Synchronize("handlescope"); | 4652 v->Synchronize("handlescope"); |
| 4529 | 4653 |
| 4530 // Iterate over the builtin code objects and code stubs in the | 4654 // Iterate over the builtin code objects and code stubs in the |
| 4531 // heap. Note that it is not necessary to iterate over code objects | 4655 // heap. Note that it is not necessary to iterate over code objects |
| 4532 // on scavenge collections. | 4656 // on scavenge collections. |
| 4533 if (mode != VISIT_ALL_IN_SCAVENGE && | 4657 if (mode != VISIT_ALL_IN_SCAVENGE && |
| 4534 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { | 4658 mode != VISIT_ALL_IN_SWEEP_NEWSPACE) { |
| 4535 isolate_->builtins()->IterateBuiltins(v); | 4659 isolate_->builtins()->IterateBuiltins(v); |
| 4536 } | 4660 } |
| 4537 v->Synchronize("builtins"); | 4661 v->Synchronize("builtins"); |
| 4538 | 4662 |
| 4539 // Iterate over global handles. | 4663 // Iterate over global handles. |
| 4540 switch (mode) { | 4664 switch (mode) { |
| 4541 case VISIT_ONLY_STRONG: | 4665 case VISIT_ONLY_STRONG: |
| 4542 isolate_->global_handles()->IterateStrongRoots(v); | 4666 isolate_->global_handles()->IterateStrongRoots(v); |
| 4543 break; | 4667 break; |
| 4544 case VISIT_ALL_IN_SCAVENGE: | 4668 case VISIT_ALL_IN_SCAVENGE: |
| 4545 isolate_->global_handles()->IterateStrongAndDependentRoots(v); | 4669 isolate_->global_handles()->IterateNewSpaceStrongAndDependentRoots(v); |
| 4546 break; | 4670 break; |
| 4547 case VISIT_ALL_IN_SWEEP_NEWSPACE: | 4671 case VISIT_ALL_IN_SWEEP_NEWSPACE: |
| 4548 case VISIT_ALL: | 4672 case VISIT_ALL: |
| 4549 isolate_->global_handles()->IterateAllRoots(v); | 4673 isolate_->global_handles()->IterateAllRoots(v); |
| 4550 break; | 4674 break; |
| 4551 } | 4675 } |
| 4552 v->Synchronize("globalhandles"); | 4676 v->Synchronize("globalhandles"); |
| 4553 | 4677 |
| 4554 // Iterate over pointers being held by inactive threads. | 4678 // Iterate over pointers being held by inactive threads. |
| 4555 isolate_->thread_manager()->Iterate(v); | 4679 isolate_->thread_manager()->Iterate(v); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4951 | 5075 |
| 4952 // Create initial objects | 5076 // Create initial objects |
| 4953 if (!CreateInitialObjects()) return false; | 5077 if (!CreateInitialObjects()) return false; |
| 4954 | 5078 |
| 4955 global_contexts_list_ = undefined_value(); | 5079 global_contexts_list_ = undefined_value(); |
| 4956 } | 5080 } |
| 4957 | 5081 |
| 4958 LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity())); | 5082 LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity())); |
| 4959 LOG(isolate_, IntPtrTEvent("heap-available", Available())); | 5083 LOG(isolate_, IntPtrTEvent("heap-available", Available())); |
| 4960 | 5084 |
| 4961 #ifdef ENABLE_LOGGING_AND_PROFILING | |
| 4962 // This should be called only after initial objects have been created. | |
| 4963 isolate_->producer_heap_profile()->Setup(); | |
| 4964 #endif | |
| 4965 | |
| 4966 store_buffer()->Setup(); | 5085 store_buffer()->Setup(); |
| 4967 | 5086 |
| 4968 return true; | 5087 return true; |
| 4969 } | 5088 } |
| 4970 | 5089 |
| 4971 | 5090 |
| 4972 void Heap::SetStackLimits() { | 5091 void Heap::SetStackLimits() { |
| 4973 ASSERT(isolate_ != NULL); | 5092 ASSERT(isolate_ != NULL); |
| 4974 ASSERT(isolate_ == isolate()); | 5093 ASSERT(isolate_ == isolate()); |
| 4975 // On 64 bit machines, pointers are generally out of range of Smis. We write | 5094 // On 64 bit machines, pointers are generally out of range of Smis. We write |
| (...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5859 } | 5978 } |
| 5860 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 5979 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 5861 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 5980 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 5862 next = chunk->next_chunk(); | 5981 next = chunk->next_chunk(); |
| 5863 isolate_->memory_allocator()->Free(chunk); | 5982 isolate_->memory_allocator()->Free(chunk); |
| 5864 } | 5983 } |
| 5865 chunks_queued_for_free_ = NULL; | 5984 chunks_queued_for_free_ = NULL; |
| 5866 } | 5985 } |
| 5867 | 5986 |
| 5868 } } // namespace v8::internal | 5987 } } // namespace v8::internal |
| OLD | NEW |