| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 } | 589 } |
| 590 } | 590 } |
| 591 } | 591 } |
| 592 | 592 |
| 593 | 593 |
| 594 void Heap::EnsureFromSpaceIsCommitted() { | 594 void Heap::EnsureFromSpaceIsCommitted() { |
| 595 if (new_space_.CommitFromSpaceIfNeeded()) return; | 595 if (new_space_.CommitFromSpaceIfNeeded()) return; |
| 596 | 596 |
| 597 // Committing memory to from space failed. | 597 // Committing memory to from space failed. |
| 598 // Try shrinking and try again. | 598 // Try shrinking and try again. |
| 599 PagedSpaces spaces; | |
| 600 for (PagedSpace* space = spaces.next(); | |
| 601 space != NULL; | |
| 602 space = spaces.next()) { | |
| 603 space->RelinkPageListInChunkOrder(true); | |
| 604 } | |
| 605 | |
| 606 Shrink(); | 599 Shrink(); |
| 607 if (new_space_.CommitFromSpaceIfNeeded()) return; | 600 if (new_space_.CommitFromSpaceIfNeeded()) return; |
| 608 | 601 |
| 609 // Committing memory to from space failed again. | 602 // Committing memory to from space failed again. |
| 610 // Memory is exhausted and we will die. | 603 // Memory is exhausted and we will die. |
| 611 V8::FatalProcessOutOfMemory("Committing semi space failed."); | 604 V8::FatalProcessOutOfMemory("Committing semi space failed."); |
| 612 } | 605 } |
| 613 | 606 |
| 614 | 607 |
| 615 void Heap::ClearJSFunctionResultCaches() { | 608 void Heap::ClearJSFunctionResultCaches() { |
| (...skipping 3771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4387 } | 4380 } |
| 4388 | 4381 |
| 4389 | 4382 |
| 4390 // Flag is set when the heap has been configured. The heap can be repeatedly | 4383 // Flag is set when the heap has been configured. The heap can be repeatedly |
| 4391 // configured through the API until it is setup. | 4384 // configured through the API until it is setup. |
| 4392 static bool heap_configured = false; | 4385 static bool heap_configured = false; |
| 4393 | 4386 |
| 4394 // TODO(1236194): Since the heap size is configurable on the command line | 4387 // TODO(1236194): Since the heap size is configurable on the command line |
| 4395 // and through the API, we should gracefully handle the case that the heap | 4388 // and through the API, we should gracefully handle the case that the heap |
| 4396 // size is not big enough to fit all the initial objects. | 4389 // size is not big enough to fit all the initial objects. |
| 4397 bool Heap::ConfigureHeap(int max_semispace_size, | 4390 bool Heap::ConfigureHeap(intptr_t max_semispace_size, |
| 4398 int max_old_gen_size, | 4391 intptr_t max_old_gen_size, |
| 4399 int max_executable_size) { | 4392 intptr_t max_executable_size) { |
| 4400 if (HasBeenSetup()) return false; | 4393 if (HasBeenSetup()) return false; |
| 4401 | 4394 |
| 4402 if (max_semispace_size > 0) max_semispace_size_ = max_semispace_size; | 4395 if (max_semispace_size > 0) max_semispace_size_ = max_semispace_size; |
| 4403 | 4396 |
| 4404 if (Snapshot::IsEnabled()) { | 4397 if (Snapshot::IsEnabled()) { |
| 4405 // If we are using a snapshot we always reserve the default amount | 4398 // If we are using a snapshot we always reserve the default amount |
| 4406 // of memory for each semispace because code in the snapshot has | 4399 // of memory for each semispace because code in the snapshot has |
| 4407 // write-barrier code that relies on the size and alignment of new | 4400 // write-barrier code that relies on the size and alignment of new |
| 4408 // space. We therefore cannot use a larger max semispace size | 4401 // space. We therefore cannot use a larger max semispace size |
| 4409 // than the default reserved semispace size. | 4402 // than the default reserved semispace size. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 4436 | 4429 |
| 4437 // The old generation is paged. | 4430 // The old generation is paged. |
| 4438 max_old_generation_size_ = RoundUp(max_old_generation_size_, Page::kPageSize); | 4431 max_old_generation_size_ = RoundUp(max_old_generation_size_, Page::kPageSize); |
| 4439 | 4432 |
| 4440 heap_configured = true; | 4433 heap_configured = true; |
| 4441 return true; | 4434 return true; |
| 4442 } | 4435 } |
| 4443 | 4436 |
| 4444 | 4437 |
| 4445 bool Heap::ConfigureHeapDefault() { | 4438 bool Heap::ConfigureHeapDefault() { |
| 4446 return ConfigureHeap(FLAG_max_new_space_size / 2 * KB, | 4439 return ConfigureHeap(static_cast<intptr_t>(FLAG_max_new_space_size / 2) * KB, |
| 4447 FLAG_max_old_space_size * MB, | 4440 static_cast<intptr_t>(FLAG_max_old_space_size) * MB, |
| 4448 FLAG_max_executable_size * MB); | 4441 static_cast<intptr_t>(FLAG_max_executable_size) * MB); |
| 4449 } | 4442 } |
| 4450 | 4443 |
| 4451 | 4444 |
| 4452 void Heap::RecordStats(HeapStats* stats, bool take_snapshot) { | 4445 void Heap::RecordStats(HeapStats* stats, bool take_snapshot) { |
| 4453 *stats->start_marker = HeapStats::kStartMarker; | 4446 *stats->start_marker = HeapStats::kStartMarker; |
| 4454 *stats->end_marker = HeapStats::kEndMarker; | 4447 *stats->end_marker = HeapStats::kEndMarker; |
| 4455 *stats->new_space_size = new_space_.SizeAsInt(); | 4448 *stats->new_space_size = new_space_.SizeAsInt(); |
| 4456 *stats->new_space_capacity = static_cast<int>(new_space_.Capacity()); | 4449 *stats->new_space_capacity = static_cast<int>(new_space_.Capacity()); |
| 4457 *stats->old_pointer_space_size = old_pointer_space_->Size(); | 4450 *stats->old_pointer_space_size = old_pointer_space_->Size(); |
| 4458 *stats->old_pointer_space_capacity = old_pointer_space_->Capacity(); | 4451 *stats->old_pointer_space_capacity = old_pointer_space_->Capacity(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4514 if (!heap_configured) { | 4507 if (!heap_configured) { |
| 4515 if (!ConfigureHeapDefault()) return false; | 4508 if (!ConfigureHeapDefault()) return false; |
| 4516 } | 4509 } |
| 4517 | 4510 |
| 4518 ScavengingVisitor::Initialize(); | 4511 ScavengingVisitor::Initialize(); |
| 4519 NewSpaceScavenger::Initialize(); | 4512 NewSpaceScavenger::Initialize(); |
| 4520 MarkCompactCollector::Initialize(); | 4513 MarkCompactCollector::Initialize(); |
| 4521 | 4514 |
| 4522 MarkMapPointersAsEncoded(false); | 4515 MarkMapPointersAsEncoded(false); |
| 4523 | 4516 |
| 4524 // Setup memory allocator and reserve a chunk of memory for new | 4517 // Setup memory allocator. |
| 4525 // space. The chunk is double the size of the requested reserved | |
| 4526 // new space size to ensure that we can find a pair of semispaces that | |
| 4527 // are contiguous and aligned to their size. | |
| 4528 if (!MemoryAllocator::Setup(MaxReserved(), MaxExecutableSize())) return false; | 4518 if (!MemoryAllocator::Setup(MaxReserved(), MaxExecutableSize())) return false; |
| 4529 void* chunk = | |
| 4530 MemoryAllocator::ReserveInitialChunk(4 * reserved_semispace_size_); | |
| 4531 if (chunk == NULL) return false; | |
| 4532 | 4519 |
| 4533 // Align the pair of semispaces to their size, which must be a power | 4520 // Setup new space. |
| 4534 // of 2. | 4521 if (!new_space_.Setup(reserved_semispace_size_)) { |
| 4535 Address new_space_start = | |
| 4536 RoundUp(reinterpret_cast<byte*>(chunk), 2 * reserved_semispace_size_); | |
| 4537 if (!new_space_.Setup(new_space_start, 2 * reserved_semispace_size_)) { | |
| 4538 return false; | 4522 return false; |
| 4539 } | 4523 } |
| 4540 | 4524 |
| 4541 // Initialize old pointer space. | 4525 // Initialize old pointer space. |
| 4542 old_pointer_space_ = | 4526 old_pointer_space_ = |
| 4543 new OldSpace(max_old_generation_size_, OLD_POINTER_SPACE, NOT_EXECUTABLE); | 4527 new OldSpace(max_old_generation_size_, OLD_POINTER_SPACE, NOT_EXECUTABLE); |
| 4544 if (old_pointer_space_ == NULL) return false; | 4528 if (old_pointer_space_ == NULL) return false; |
| 4545 if (!old_pointer_space_->Setup(NULL, 0)) return false; | 4529 if (!old_pointer_space_->Setup()) return false; |
| 4546 | 4530 |
| 4547 // Initialize old data space. | 4531 // Initialize old data space. |
| 4548 old_data_space_ = | 4532 old_data_space_ = |
| 4549 new OldSpace(max_old_generation_size_, OLD_DATA_SPACE, NOT_EXECUTABLE); | 4533 new OldSpace(max_old_generation_size_, OLD_DATA_SPACE, NOT_EXECUTABLE); |
| 4550 if (old_data_space_ == NULL) return false; | 4534 if (old_data_space_ == NULL) return false; |
| 4551 if (!old_data_space_->Setup(NULL, 0)) return false; | 4535 if (!old_data_space_->Setup()) return false; |
| 4552 | 4536 |
| 4553 // Initialize the code space, set its maximum capacity to the old | 4537 // Initialize the code space, set its maximum capacity to the old |
| 4554 // generation size. It needs executable memory. | 4538 // generation size. It needs executable memory. |
| 4555 // On 64-bit platform(s), we put all code objects in a 2 GB range of | 4539 // On 64-bit platform(s), we put all code objects in a 2 GB range of |
| 4556 // virtual address space, so that they can call each other with near calls. | 4540 // virtual address space, so that they can call each other with near calls. |
| 4557 if (code_range_size_ > 0) { | 4541 if (code_range_size_ > 0) { |
| 4558 if (!CodeRange::Setup(code_range_size_)) { | 4542 if (!CodeRange::Setup(code_range_size_)) { |
| 4559 return false; | 4543 return false; |
| 4560 } | 4544 } |
| 4561 } | 4545 } |
| 4562 | 4546 |
| 4563 code_space_ = | 4547 code_space_ = |
| 4564 new OldSpace(max_old_generation_size_, CODE_SPACE, EXECUTABLE); | 4548 new OldSpace(max_old_generation_size_, CODE_SPACE, EXECUTABLE); |
| 4565 if (code_space_ == NULL) return false; | 4549 if (code_space_ == NULL) return false; |
| 4566 if (!code_space_->Setup(NULL, 0)) return false; | 4550 if (!code_space_->Setup()) return false; |
| 4567 | 4551 |
| 4568 // Initialize map space. | 4552 // Initialize map space. |
| 4569 map_space_ = new MapSpace(FLAG_use_big_map_space | 4553 map_space_ = new MapSpace(max_old_generation_size_, |
| 4570 ? max_old_generation_size_ | 4554 FLAG_max_map_space_pages, |
| 4571 : MapSpace::kMaxMapPageIndex * Page::kPageSize, | 4555 MAP_SPACE); |
| 4572 FLAG_max_map_space_pages, | |
| 4573 MAP_SPACE); | |
| 4574 if (map_space_ == NULL) return false; | 4556 if (map_space_ == NULL) return false; |
| 4575 if (!map_space_->Setup(NULL, 0)) return false; | 4557 if (!map_space_->Setup()) return false; |
| 4576 | 4558 |
| 4577 // Initialize global property cell space. | 4559 // Initialize global property cell space. |
| 4578 cell_space_ = new CellSpace(max_old_generation_size_, CELL_SPACE); | 4560 cell_space_ = new CellSpace(max_old_generation_size_, CELL_SPACE); |
| 4579 if (cell_space_ == NULL) return false; | 4561 if (cell_space_ == NULL) return false; |
| 4580 if (!cell_space_->Setup(NULL, 0)) return false; | 4562 if (!cell_space_->Setup()) return false; |
| 4581 | 4563 |
| 4582 // The large object code space may contain code or data. We set the memory | 4564 // The large object code space may contain code or data. We set the memory |
| 4583 // to be non-executable here for safety, but this means we need to enable it | 4565 // to be non-executable here for safety, but this means we need to enable it |
| 4584 // explicitly when allocating large code objects. | 4566 // explicitly when allocating large code objects. |
| 4585 lo_space_ = new LargeObjectSpace(LO_SPACE); | 4567 lo_space_ = new LargeObjectSpace(LO_SPACE); |
| 4586 if (lo_space_ == NULL) return false; | 4568 if (lo_space_ == NULL) return false; |
| 4587 if (!lo_space_->Setup()) return false; | 4569 if (!lo_space_->Setup()) return false; |
| 4588 | 4570 |
| 4589 if (create_heap_objects) { | 4571 if (create_heap_objects) { |
| 4590 // Create initial maps. | 4572 // Create initial maps. |
| (...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5507 void ExternalStringTable::TearDown() { | 5489 void ExternalStringTable::TearDown() { |
| 5508 new_space_strings_.Free(); | 5490 new_space_strings_.Free(); |
| 5509 old_space_strings_.Free(); | 5491 old_space_strings_.Free(); |
| 5510 } | 5492 } |
| 5511 | 5493 |
| 5512 | 5494 |
| 5513 List<Object*> ExternalStringTable::new_space_strings_; | 5495 List<Object*> ExternalStringTable::new_space_strings_; |
| 5514 List<Object*> ExternalStringTable::old_space_strings_; | 5496 List<Object*> ExternalStringTable::old_space_strings_; |
| 5515 | 5497 |
| 5516 } } // namespace v8::internal | 5498 } } // namespace v8::internal |
| OLD | NEW |