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 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 169 } |
170 | 170 |
171 memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); | 171 memset(roots_, 0, sizeof(roots_[0]) * kRootListLength); |
172 global_contexts_list_ = NULL; | 172 global_contexts_list_ = NULL; |
173 mark_compact_collector_.heap_ = this; | 173 mark_compact_collector_.heap_ = this; |
174 external_string_table_.heap_ = this; | 174 external_string_table_.heap_ = this; |
175 } | 175 } |
176 | 176 |
177 | 177 |
178 intptr_t Heap::Capacity() { | 178 intptr_t Heap::Capacity() { |
179 if (!HasBeenSetup()) return 0; | 179 if (!HasBeenSetUp()) return 0; |
180 | 180 |
181 return new_space_.Capacity() + | 181 return new_space_.Capacity() + |
182 old_pointer_space_->Capacity() + | 182 old_pointer_space_->Capacity() + |
183 old_data_space_->Capacity() + | 183 old_data_space_->Capacity() + |
184 code_space_->Capacity() + | 184 code_space_->Capacity() + |
185 map_space_->Capacity() + | 185 map_space_->Capacity() + |
186 cell_space_->Capacity(); | 186 cell_space_->Capacity(); |
187 } | 187 } |
188 | 188 |
189 | 189 |
190 intptr_t Heap::CommittedMemory() { | 190 intptr_t Heap::CommittedMemory() { |
191 if (!HasBeenSetup()) return 0; | 191 if (!HasBeenSetUp()) return 0; |
192 | 192 |
193 return new_space_.CommittedMemory() + | 193 return new_space_.CommittedMemory() + |
194 old_pointer_space_->CommittedMemory() + | 194 old_pointer_space_->CommittedMemory() + |
195 old_data_space_->CommittedMemory() + | 195 old_data_space_->CommittedMemory() + |
196 code_space_->CommittedMemory() + | 196 code_space_->CommittedMemory() + |
197 map_space_->CommittedMemory() + | 197 map_space_->CommittedMemory() + |
198 cell_space_->CommittedMemory() + | 198 cell_space_->CommittedMemory() + |
199 lo_space_->Size(); | 199 lo_space_->Size(); |
200 } | 200 } |
201 | 201 |
202 intptr_t Heap::CommittedMemoryExecutable() { | 202 intptr_t Heap::CommittedMemoryExecutable() { |
203 if (!HasBeenSetup()) return 0; | 203 if (!HasBeenSetUp()) return 0; |
204 | 204 |
205 return isolate()->memory_allocator()->SizeExecutable(); | 205 return isolate()->memory_allocator()->SizeExecutable(); |
206 } | 206 } |
207 | 207 |
208 | 208 |
209 intptr_t Heap::Available() { | 209 intptr_t Heap::Available() { |
210 if (!HasBeenSetup()) return 0; | 210 if (!HasBeenSetUp()) return 0; |
211 | 211 |
212 return new_space_.Available() + | 212 return new_space_.Available() + |
213 old_pointer_space_->Available() + | 213 old_pointer_space_->Available() + |
214 old_data_space_->Available() + | 214 old_data_space_->Available() + |
215 code_space_->Available() + | 215 code_space_->Available() + |
216 map_space_->Available() + | 216 map_space_->Available() + |
217 cell_space_->Available(); | 217 cell_space_->Available(); |
218 } | 218 } |
219 | 219 |
220 | 220 |
221 bool Heap::HasBeenSetup() { | 221 bool Heap::HasBeenSetUp() { |
222 return old_pointer_space_ != NULL && | 222 return old_pointer_space_ != NULL && |
223 old_data_space_ != NULL && | 223 old_data_space_ != NULL && |
224 code_space_ != NULL && | 224 code_space_ != NULL && |
225 map_space_ != NULL && | 225 map_space_ != NULL && |
226 cell_space_ != NULL && | 226 cell_space_ != NULL && |
227 lo_space_ != NULL; | 227 lo_space_ != NULL; |
228 } | 228 } |
229 | 229 |
230 | 230 |
231 int Heap::GcSafeSizeOfOldObject(HeapObject* object) { | 231 int Heap::GcSafeSizeOfOldObject(HeapObject* object) { |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1347 Context::NEXT_CONTEXT_LINK, | 1347 Context::NEXT_CONTEXT_LINK, |
1348 Heap::undefined_value(), | 1348 Heap::undefined_value(), |
1349 UPDATE_WRITE_BARRIER); | 1349 UPDATE_WRITE_BARRIER); |
1350 } | 1350 } |
1351 | 1351 |
1352 // Update the head of the list of contexts. | 1352 // Update the head of the list of contexts. |
1353 global_contexts_list_ = head; | 1353 global_contexts_list_ = head; |
1354 } | 1354 } |
1355 | 1355 |
1356 | 1356 |
| 1357 void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) { |
| 1358 AssertNoAllocation no_allocation; |
| 1359 |
| 1360 class VisitorAdapter : public ObjectVisitor { |
| 1361 public: |
| 1362 explicit VisitorAdapter(v8::ExternalResourceVisitor* visitor) |
| 1363 : visitor_(visitor) {} |
| 1364 virtual void VisitPointers(Object** start, Object** end) { |
| 1365 for (Object** p = start; p < end; p++) { |
| 1366 if ((*p)->IsExternalString()) { |
| 1367 visitor_->VisitExternalString(Utils::ToLocal( |
| 1368 Handle<String>(String::cast(*p)))); |
| 1369 } |
| 1370 } |
| 1371 } |
| 1372 private: |
| 1373 v8::ExternalResourceVisitor* visitor_; |
| 1374 } visitor_adapter(visitor); |
| 1375 external_string_table_.Iterate(&visitor_adapter); |
| 1376 } |
| 1377 |
| 1378 |
1357 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> { | 1379 class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> { |
1358 public: | 1380 public: |
1359 static inline void VisitPointer(Heap* heap, Object** p) { | 1381 static inline void VisitPointer(Heap* heap, Object** p) { |
1360 Object* object = *p; | 1382 Object* object = *p; |
1361 if (!heap->InNewSpace(object)) return; | 1383 if (!heap->InNewSpace(object)) return; |
1362 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), | 1384 Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p), |
1363 reinterpret_cast<HeapObject*>(object)); | 1385 reinterpret_cast<HeapObject*>(object)); |
1364 } | 1386 } |
1365 }; | 1387 }; |
1366 | 1388 |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 code_cache->set_normal_type_cache(undefined_value(), SKIP_WRITE_BARRIER); | 1884 code_cache->set_normal_type_cache(undefined_value(), SKIP_WRITE_BARRIER); |
1863 return code_cache; | 1885 return code_cache; |
1864 } | 1886 } |
1865 | 1887 |
1866 | 1888 |
1867 MaybeObject* Heap::AllocatePolymorphicCodeCache() { | 1889 MaybeObject* Heap::AllocatePolymorphicCodeCache() { |
1868 return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE); | 1890 return AllocateStruct(POLYMORPHIC_CODE_CACHE_TYPE); |
1869 } | 1891 } |
1870 | 1892 |
1871 | 1893 |
| 1894 MaybeObject* Heap::AllocateAccessorPair() { |
| 1895 Object* result; |
| 1896 { MaybeObject* maybe_result = AllocateStruct(ACCESSOR_PAIR_TYPE); |
| 1897 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1898 } |
| 1899 AccessorPair* accessors = AccessorPair::cast(result); |
| 1900 // Later we will have to distinguish between undefined and the hole... |
| 1901 // accessors->set_getter(the_hole_value(), SKIP_WRITE_BARRIER); |
| 1902 // accessors->set_setter(the_hole_value(), SKIP_WRITE_BARRIER); |
| 1903 return accessors; |
| 1904 } |
| 1905 |
| 1906 |
1872 const Heap::StringTypeTable Heap::string_type_table[] = { | 1907 const Heap::StringTypeTable Heap::string_type_table[] = { |
1873 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ | 1908 #define STRING_TYPE_ELEMENT(type, size, name, camel_name) \ |
1874 {type, size, k##camel_name##MapRootIndex}, | 1909 {type, size, k##camel_name##MapRootIndex}, |
1875 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) | 1910 STRING_TYPE_LIST(STRING_TYPE_ELEMENT) |
1876 #undef STRING_TYPE_ELEMENT | 1911 #undef STRING_TYPE_ELEMENT |
1877 }; | 1912 }; |
1878 | 1913 |
1879 | 1914 |
1880 const Heap::ConstantSymbolTable Heap::constant_symbol_table[] = { | 1915 const Heap::ConstantSymbolTable Heap::constant_symbol_table[] = { |
1881 #define CONSTANT_SYMBOL_ELEMENT(name, contents) \ | 1916 #define CONSTANT_SYMBOL_ELEMENT(name, contents) \ |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2421 | 2456 |
2422 // Allocate the foreign for __proto__. | 2457 // Allocate the foreign for __proto__. |
2423 { MaybeObject* maybe_obj = | 2458 { MaybeObject* maybe_obj = |
2424 AllocateForeign((Address) &Accessors::ObjectPrototype); | 2459 AllocateForeign((Address) &Accessors::ObjectPrototype); |
2425 if (!maybe_obj->ToObject(&obj)) return false; | 2460 if (!maybe_obj->ToObject(&obj)) return false; |
2426 } | 2461 } |
2427 set_prototype_accessors(Foreign::cast(obj)); | 2462 set_prototype_accessors(Foreign::cast(obj)); |
2428 | 2463 |
2429 // Allocate the code_stubs dictionary. The initial size is set to avoid | 2464 // Allocate the code_stubs dictionary. The initial size is set to avoid |
2430 // expanding the dictionary during bootstrapping. | 2465 // expanding the dictionary during bootstrapping. |
2431 { MaybeObject* maybe_obj = NumberDictionary::Allocate(128); | 2466 { MaybeObject* maybe_obj = UnseededNumberDictionary::Allocate(128); |
2432 if (!maybe_obj->ToObject(&obj)) return false; | 2467 if (!maybe_obj->ToObject(&obj)) return false; |
2433 } | 2468 } |
2434 set_code_stubs(NumberDictionary::cast(obj)); | 2469 set_code_stubs(UnseededNumberDictionary::cast(obj)); |
2435 | 2470 |
2436 | 2471 |
2437 // Allocate the non_monomorphic_cache used in stub-cache.cc. The initial size | 2472 // Allocate the non_monomorphic_cache used in stub-cache.cc. The initial size |
2438 // is set to avoid expanding the dictionary during bootstrapping. | 2473 // is set to avoid expanding the dictionary during bootstrapping. |
2439 { MaybeObject* maybe_obj = NumberDictionary::Allocate(64); | 2474 { MaybeObject* maybe_obj = UnseededNumberDictionary::Allocate(64); |
2440 if (!maybe_obj->ToObject(&obj)) return false; | 2475 if (!maybe_obj->ToObject(&obj)) return false; |
2441 } | 2476 } |
2442 set_non_monomorphic_cache(NumberDictionary::cast(obj)); | 2477 set_non_monomorphic_cache(UnseededNumberDictionary::cast(obj)); |
2443 | 2478 |
2444 { MaybeObject* maybe_obj = AllocatePolymorphicCodeCache(); | 2479 { MaybeObject* maybe_obj = AllocatePolymorphicCodeCache(); |
2445 if (!maybe_obj->ToObject(&obj)) return false; | 2480 if (!maybe_obj->ToObject(&obj)) return false; |
2446 } | 2481 } |
2447 set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj)); | 2482 set_polymorphic_code_cache(PolymorphicCodeCache::cast(obj)); |
2448 | 2483 |
2449 set_instanceof_cache_function(Smi::FromInt(0)); | 2484 set_instanceof_cache_function(Smi::FromInt(0)); |
2450 set_instanceof_cache_map(Smi::FromInt(0)); | 2485 set_instanceof_cache_map(Smi::FromInt(0)); |
2451 set_instanceof_cache_answer(Smi::FromInt(0)); | 2486 set_instanceof_cache_answer(Smi::FromInt(0)); |
2452 | 2487 |
(...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3787 } | 3822 } |
3788 JSObject* global = JSObject::cast(obj); | 3823 JSObject* global = JSObject::cast(obj); |
3789 InitializeJSObjectFromMap(global, dictionary, map); | 3824 InitializeJSObjectFromMap(global, dictionary, map); |
3790 | 3825 |
3791 // Create a new map for the global object. | 3826 // Create a new map for the global object. |
3792 { MaybeObject* maybe_obj = map->CopyDropDescriptors(); | 3827 { MaybeObject* maybe_obj = map->CopyDropDescriptors(); |
3793 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3828 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3794 } | 3829 } |
3795 Map* new_map = Map::cast(obj); | 3830 Map* new_map = Map::cast(obj); |
3796 | 3831 |
3797 // Setup the global object as a normalized object. | 3832 // Set up the global object as a normalized object. |
3798 global->set_map(new_map); | 3833 global->set_map(new_map); |
3799 global->map()->clear_instance_descriptors(); | 3834 global->map()->clear_instance_descriptors(); |
3800 global->set_properties(dictionary); | 3835 global->set_properties(dictionary); |
3801 | 3836 |
3802 // Make sure result is a global object with properties in dictionary. | 3837 // Make sure result is a global object with properties in dictionary. |
3803 ASSERT(global->IsGlobalObject()); | 3838 ASSERT(global->IsGlobalObject()); |
3804 ASSERT(!global->HasFastProperties()); | 3839 ASSERT(!global->HasFastProperties()); |
3805 return global; | 3840 return global; |
3806 } | 3841 } |
3807 | 3842 |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4720 ASSERT((contexts_disposed_ == 0) || !incremental_marking()->IsStopped()); | 4755 ASSERT((contexts_disposed_ == 0) || !incremental_marking()->IsStopped()); |
4721 if (uncommit) UncommitFromSpace(); | 4756 if (uncommit) UncommitFromSpace(); |
4722 | 4757 |
4723 return finished; | 4758 return finished; |
4724 } | 4759 } |
4725 | 4760 |
4726 | 4761 |
4727 #ifdef DEBUG | 4762 #ifdef DEBUG |
4728 | 4763 |
4729 void Heap::Print() { | 4764 void Heap::Print() { |
4730 if (!HasBeenSetup()) return; | 4765 if (!HasBeenSetUp()) return; |
4731 isolate()->PrintStack(); | 4766 isolate()->PrintStack(); |
4732 AllSpaces spaces; | 4767 AllSpaces spaces; |
4733 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) | 4768 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) |
4734 space->Print(); | 4769 space->Print(); |
4735 } | 4770 } |
4736 | 4771 |
4737 | 4772 |
4738 void Heap::ReportCodeStatistics(const char* title) { | 4773 void Heap::ReportCodeStatistics(const char* title) { |
4739 PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title); | 4774 PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title); |
4740 PagedSpace::ResetCodeStatistics(); | 4775 PagedSpace::ResetCodeStatistics(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4785 | 4820 |
4786 #endif // DEBUG | 4821 #endif // DEBUG |
4787 | 4822 |
4788 bool Heap::Contains(HeapObject* value) { | 4823 bool Heap::Contains(HeapObject* value) { |
4789 return Contains(value->address()); | 4824 return Contains(value->address()); |
4790 } | 4825 } |
4791 | 4826 |
4792 | 4827 |
4793 bool Heap::Contains(Address addr) { | 4828 bool Heap::Contains(Address addr) { |
4794 if (OS::IsOutsideAllocatedSpace(addr)) return false; | 4829 if (OS::IsOutsideAllocatedSpace(addr)) return false; |
4795 return HasBeenSetup() && | 4830 return HasBeenSetUp() && |
4796 (new_space_.ToSpaceContains(addr) || | 4831 (new_space_.ToSpaceContains(addr) || |
4797 old_pointer_space_->Contains(addr) || | 4832 old_pointer_space_->Contains(addr) || |
4798 old_data_space_->Contains(addr) || | 4833 old_data_space_->Contains(addr) || |
4799 code_space_->Contains(addr) || | 4834 code_space_->Contains(addr) || |
4800 map_space_->Contains(addr) || | 4835 map_space_->Contains(addr) || |
4801 cell_space_->Contains(addr) || | 4836 cell_space_->Contains(addr) || |
4802 lo_space_->SlowContains(addr)); | 4837 lo_space_->SlowContains(addr)); |
4803 } | 4838 } |
4804 | 4839 |
4805 | 4840 |
4806 bool Heap::InSpace(HeapObject* value, AllocationSpace space) { | 4841 bool Heap::InSpace(HeapObject* value, AllocationSpace space) { |
4807 return InSpace(value->address(), space); | 4842 return InSpace(value->address(), space); |
4808 } | 4843 } |
4809 | 4844 |
4810 | 4845 |
4811 bool Heap::InSpace(Address addr, AllocationSpace space) { | 4846 bool Heap::InSpace(Address addr, AllocationSpace space) { |
4812 if (OS::IsOutsideAllocatedSpace(addr)) return false; | 4847 if (OS::IsOutsideAllocatedSpace(addr)) return false; |
4813 if (!HasBeenSetup()) return false; | 4848 if (!HasBeenSetUp()) return false; |
4814 | 4849 |
4815 switch (space) { | 4850 switch (space) { |
4816 case NEW_SPACE: | 4851 case NEW_SPACE: |
4817 return new_space_.ToSpaceContains(addr); | 4852 return new_space_.ToSpaceContains(addr); |
4818 case OLD_POINTER_SPACE: | 4853 case OLD_POINTER_SPACE: |
4819 return old_pointer_space_->Contains(addr); | 4854 return old_pointer_space_->Contains(addr); |
4820 case OLD_DATA_SPACE: | 4855 case OLD_DATA_SPACE: |
4821 return old_data_space_->Contains(addr); | 4856 return old_data_space_->Contains(addr); |
4822 case CODE_SPACE: | 4857 case CODE_SPACE: |
4823 return code_space_->Contains(addr); | 4858 return code_space_->Contains(addr); |
4824 case MAP_SPACE: | 4859 case MAP_SPACE: |
4825 return map_space_->Contains(addr); | 4860 return map_space_->Contains(addr); |
4826 case CELL_SPACE: | 4861 case CELL_SPACE: |
4827 return cell_space_->Contains(addr); | 4862 return cell_space_->Contains(addr); |
4828 case LO_SPACE: | 4863 case LO_SPACE: |
4829 return lo_space_->SlowContains(addr); | 4864 return lo_space_->SlowContains(addr); |
4830 } | 4865 } |
4831 | 4866 |
4832 return false; | 4867 return false; |
4833 } | 4868 } |
4834 | 4869 |
4835 | 4870 |
4836 #ifdef DEBUG | 4871 #ifdef DEBUG |
4837 void Heap::Verify() { | 4872 void Heap::Verify() { |
4838 ASSERT(HasBeenSetup()); | 4873 ASSERT(HasBeenSetUp()); |
4839 | 4874 |
4840 store_buffer()->Verify(); | 4875 store_buffer()->Verify(); |
4841 | 4876 |
4842 VerifyPointersVisitor visitor; | 4877 VerifyPointersVisitor visitor; |
4843 IterateRoots(&visitor, VISIT_ONLY_STRONG); | 4878 IterateRoots(&visitor, VISIT_ONLY_STRONG); |
4844 | 4879 |
4845 new_space_.Verify(); | 4880 new_space_.Verify(); |
4846 | 4881 |
4847 old_pointer_space_->Verify(&visitor); | 4882 old_pointer_space_->Verify(&visitor); |
4848 map_space_->Verify(&visitor); | 4883 map_space_->Verify(&visitor); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5255 // checking of the sync flag in the snapshot would fail. | 5290 // checking of the sync flag in the snapshot would fail. |
5256 } | 5291 } |
5257 | 5292 |
5258 | 5293 |
5259 // TODO(1236194): Since the heap size is configurable on the command line | 5294 // TODO(1236194): Since the heap size is configurable on the command line |
5260 // and through the API, we should gracefully handle the case that the heap | 5295 // and through the API, we should gracefully handle the case that the heap |
5261 // size is not big enough to fit all the initial objects. | 5296 // size is not big enough to fit all the initial objects. |
5262 bool Heap::ConfigureHeap(int max_semispace_size, | 5297 bool Heap::ConfigureHeap(int max_semispace_size, |
5263 intptr_t max_old_gen_size, | 5298 intptr_t max_old_gen_size, |
5264 intptr_t max_executable_size) { | 5299 intptr_t max_executable_size) { |
5265 if (HasBeenSetup()) return false; | 5300 if (HasBeenSetUp()) return false; |
5266 | 5301 |
5267 if (max_semispace_size > 0) { | 5302 if (max_semispace_size > 0) { |
5268 if (max_semispace_size < Page::kPageSize) { | 5303 if (max_semispace_size < Page::kPageSize) { |
5269 max_semispace_size = Page::kPageSize; | 5304 max_semispace_size = Page::kPageSize; |
5270 if (FLAG_trace_gc) { | 5305 if (FLAG_trace_gc) { |
5271 PrintF("Max semispace size cannot be less than %dkbytes\n", | 5306 PrintF("Max semispace size cannot be less than %dkbytes\n", |
5272 Page::kPageSize >> 10); | 5307 Page::kPageSize >> 10); |
5273 } | 5308 } |
5274 } | 5309 } |
5275 max_semispace_size_ = max_semispace_size; | 5310 max_semispace_size_ = max_semispace_size; |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5544 Object* search_target_; | 5579 Object* search_target_; |
5545 bool found_target_; | 5580 bool found_target_; |
5546 List<Object*> object_stack_; | 5581 List<Object*> object_stack_; |
5547 Heap* heap_; | 5582 Heap* heap_; |
5548 | 5583 |
5549 friend class Heap; | 5584 friend class Heap; |
5550 }; | 5585 }; |
5551 | 5586 |
5552 #endif | 5587 #endif |
5553 | 5588 |
5554 bool Heap::Setup(bool create_heap_objects) { | 5589 bool Heap::SetUp(bool create_heap_objects) { |
5555 #ifdef DEBUG | 5590 #ifdef DEBUG |
5556 allocation_timeout_ = FLAG_gc_interval; | 5591 allocation_timeout_ = FLAG_gc_interval; |
5557 debug_utils_ = new HeapDebugUtils(this); | 5592 debug_utils_ = new HeapDebugUtils(this); |
5558 #endif | 5593 #endif |
5559 | 5594 |
5560 // Initialize heap spaces and initial maps and objects. Whenever something | 5595 // Initialize heap spaces and initial maps and objects. Whenever something |
5561 // goes wrong, just return false. The caller should check the results and | 5596 // goes wrong, just return false. The caller should check the results and |
5562 // call Heap::TearDown() to release allocated memory. | 5597 // call Heap::TearDown() to release allocated memory. |
5563 // | 5598 // |
5564 // If the heap is not yet configured (eg, through the API), configure it. | 5599 // If the heap is not yet configured (eg, through the API), configure it. |
5565 // Configuration is based on the flags new-space-size (really the semispace | 5600 // Configuration is based on the flags new-space-size (really the semispace |
5566 // size) and old-space-size if set or the initial values of semispace_size_ | 5601 // size) and old-space-size if set or the initial values of semispace_size_ |
5567 // and old_generation_size_ otherwise. | 5602 // and old_generation_size_ otherwise. |
5568 if (!configured_) { | 5603 if (!configured_) { |
5569 if (!ConfigureHeapDefault()) return false; | 5604 if (!ConfigureHeapDefault()) return false; |
5570 } | 5605 } |
5571 | 5606 |
5572 gc_initializer_mutex->Lock(); | 5607 gc_initializer_mutex->Lock(); |
5573 static bool initialized_gc = false; | 5608 static bool initialized_gc = false; |
5574 if (!initialized_gc) { | 5609 if (!initialized_gc) { |
5575 initialized_gc = true; | 5610 initialized_gc = true; |
5576 InitializeScavengingVisitorsTables(); | 5611 InitializeScavengingVisitorsTables(); |
5577 NewSpaceScavenger::Initialize(); | 5612 NewSpaceScavenger::Initialize(); |
5578 MarkCompactCollector::Initialize(); | 5613 MarkCompactCollector::Initialize(); |
5579 } | 5614 } |
5580 gc_initializer_mutex->Unlock(); | 5615 gc_initializer_mutex->Unlock(); |
5581 | 5616 |
5582 MarkMapPointersAsEncoded(false); | 5617 MarkMapPointersAsEncoded(false); |
5583 | 5618 |
5584 // Setup memory allocator. | 5619 // Set up memory allocator. |
5585 if (!isolate_->memory_allocator()->Setup(MaxReserved(), MaxExecutableSize())) | 5620 if (!isolate_->memory_allocator()->SetUp(MaxReserved(), MaxExecutableSize())) |
5586 return false; | 5621 return false; |
5587 | 5622 |
5588 // Setup new space. | 5623 // Set up new space. |
5589 if (!new_space_.Setup(reserved_semispace_size_, max_semispace_size_)) { | 5624 if (!new_space_.SetUp(reserved_semispace_size_, max_semispace_size_)) { |
5590 return false; | 5625 return false; |
5591 } | 5626 } |
5592 | 5627 |
5593 // Initialize old pointer space. | 5628 // Initialize old pointer space. |
5594 old_pointer_space_ = | 5629 old_pointer_space_ = |
5595 new OldSpace(this, | 5630 new OldSpace(this, |
5596 max_old_generation_size_, | 5631 max_old_generation_size_, |
5597 OLD_POINTER_SPACE, | 5632 OLD_POINTER_SPACE, |
5598 NOT_EXECUTABLE); | 5633 NOT_EXECUTABLE); |
5599 if (old_pointer_space_ == NULL) return false; | 5634 if (old_pointer_space_ == NULL) return false; |
5600 if (!old_pointer_space_->Setup()) return false; | 5635 if (!old_pointer_space_->SetUp()) return false; |
5601 | 5636 |
5602 // Initialize old data space. | 5637 // Initialize old data space. |
5603 old_data_space_ = | 5638 old_data_space_ = |
5604 new OldSpace(this, | 5639 new OldSpace(this, |
5605 max_old_generation_size_, | 5640 max_old_generation_size_, |
5606 OLD_DATA_SPACE, | 5641 OLD_DATA_SPACE, |
5607 NOT_EXECUTABLE); | 5642 NOT_EXECUTABLE); |
5608 if (old_data_space_ == NULL) return false; | 5643 if (old_data_space_ == NULL) return false; |
5609 if (!old_data_space_->Setup()) return false; | 5644 if (!old_data_space_->SetUp()) return false; |
5610 | 5645 |
5611 // Initialize the code space, set its maximum capacity to the old | 5646 // Initialize the code space, set its maximum capacity to the old |
5612 // generation size. It needs executable memory. | 5647 // generation size. It needs executable memory. |
5613 // On 64-bit platform(s), we put all code objects in a 2 GB range of | 5648 // On 64-bit platform(s), we put all code objects in a 2 GB range of |
5614 // virtual address space, so that they can call each other with near calls. | 5649 // virtual address space, so that they can call each other with near calls. |
5615 if (code_range_size_ > 0) { | 5650 if (code_range_size_ > 0) { |
5616 if (!isolate_->code_range()->Setup(code_range_size_)) { | 5651 if (!isolate_->code_range()->SetUp(code_range_size_)) { |
5617 return false; | 5652 return false; |
5618 } | 5653 } |
5619 } | 5654 } |
5620 | 5655 |
5621 code_space_ = | 5656 code_space_ = |
5622 new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE); | 5657 new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE); |
5623 if (code_space_ == NULL) return false; | 5658 if (code_space_ == NULL) return false; |
5624 if (!code_space_->Setup()) return false; | 5659 if (!code_space_->SetUp()) return false; |
5625 | 5660 |
5626 // Initialize map space. | 5661 // Initialize map space. |
5627 map_space_ = new MapSpace(this, | 5662 map_space_ = new MapSpace(this, |
5628 max_old_generation_size_, | 5663 max_old_generation_size_, |
5629 FLAG_max_map_space_pages, | 5664 FLAG_max_map_space_pages, |
5630 MAP_SPACE); | 5665 MAP_SPACE); |
5631 if (map_space_ == NULL) return false; | 5666 if (map_space_ == NULL) return false; |
5632 if (!map_space_->Setup()) return false; | 5667 if (!map_space_->SetUp()) return false; |
5633 | 5668 |
5634 // Initialize global property cell space. | 5669 // Initialize global property cell space. |
5635 cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE); | 5670 cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE); |
5636 if (cell_space_ == NULL) return false; | 5671 if (cell_space_ == NULL) return false; |
5637 if (!cell_space_->Setup()) return false; | 5672 if (!cell_space_->SetUp()) return false; |
5638 | 5673 |
5639 // The large object code space may contain code or data. We set the memory | 5674 // The large object code space may contain code or data. We set the memory |
5640 // to be non-executable here for safety, but this means we need to enable it | 5675 // to be non-executable here for safety, but this means we need to enable it |
5641 // explicitly when allocating large code objects. | 5676 // explicitly when allocating large code objects. |
5642 lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE); | 5677 lo_space_ = new LargeObjectSpace(this, max_old_generation_size_, LO_SPACE); |
5643 if (lo_space_ == NULL) return false; | 5678 if (lo_space_ == NULL) return false; |
5644 if (!lo_space_->Setup()) return false; | 5679 if (!lo_space_->SetUp()) return false; |
5645 | 5680 |
5646 // Setup the seed that is used to randomize the string hash function. | 5681 // Set up the seed that is used to randomize the string hash function. |
5647 ASSERT(string_hash_seed() == 0); | 5682 ASSERT(hash_seed() == 0); |
5648 if (FLAG_randomize_string_hashes) { | 5683 if (FLAG_randomize_hashes) { |
5649 if (FLAG_string_hash_seed == 0) { | 5684 if (FLAG_hash_seed == 0) { |
5650 set_string_hash_seed( | 5685 set_hash_seed( |
5651 Smi::FromInt(V8::RandomPrivate(isolate()) & 0x3fffffff)); | 5686 Smi::FromInt(V8::RandomPrivate(isolate()) & 0x3fffffff)); |
5652 } else { | 5687 } else { |
5653 set_string_hash_seed(Smi::FromInt(FLAG_string_hash_seed)); | 5688 set_hash_seed(Smi::FromInt(FLAG_hash_seed)); |
5654 } | 5689 } |
5655 } | 5690 } |
5656 | 5691 |
5657 if (create_heap_objects) { | 5692 if (create_heap_objects) { |
5658 // Create initial maps. | 5693 // Create initial maps. |
5659 if (!CreateInitialMaps()) return false; | 5694 if (!CreateInitialMaps()) return false; |
5660 if (!CreateApiObjects()) return false; | 5695 if (!CreateApiObjects()) return false; |
5661 | 5696 |
5662 // Create initial objects | 5697 // Create initial objects |
5663 if (!CreateInitialObjects()) return false; | 5698 if (!CreateInitialObjects()) return false; |
5664 | 5699 |
5665 global_contexts_list_ = undefined_value(); | 5700 global_contexts_list_ = undefined_value(); |
5666 } | 5701 } |
5667 | 5702 |
5668 LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity())); | 5703 LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity())); |
5669 LOG(isolate_, IntPtrTEvent("heap-available", Available())); | 5704 LOG(isolate_, IntPtrTEvent("heap-available", Available())); |
5670 | 5705 |
5671 store_buffer()->Setup(); | 5706 store_buffer()->SetUp(); |
5672 | 5707 |
5673 return true; | 5708 return true; |
5674 } | 5709 } |
5675 | 5710 |
5676 | 5711 |
5677 void Heap::SetStackLimits() { | 5712 void Heap::SetStackLimits() { |
5678 ASSERT(isolate_ != NULL); | 5713 ASSERT(isolate_ != NULL); |
5679 ASSERT(isolate_ == isolate()); | 5714 ASSERT(isolate_ == isolate()); |
5680 // On 64 bit machines, pointers are generally out of range of Smis. We write | 5715 // On 64 bit machines, pointers are generally out of range of Smis. We write |
5681 // something that looks like an out of range Smi to the GC. | 5716 // something that looks like an out of range Smi to the GC. |
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6619 isolate_->heap()->store_buffer()->Compact(); | 6654 isolate_->heap()->store_buffer()->Compact(); |
6620 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6655 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
6621 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6656 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
6622 next = chunk->next_chunk(); | 6657 next = chunk->next_chunk(); |
6623 isolate_->memory_allocator()->Free(chunk); | 6658 isolate_->memory_allocator()->Free(chunk); |
6624 } | 6659 } |
6625 chunks_queued_for_free_ = NULL; | 6660 chunks_queued_for_free_ = NULL; |
6626 } | 6661 } |
6627 | 6662 |
6628 } } // namespace v8::internal | 6663 } } // namespace v8::internal |
OLD | NEW |