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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 allocation_list_[current_allocation_block_index_].start += *allocated; | 238 allocation_list_[current_allocation_block_index_].start += *allocated; |
239 allocation_list_[current_allocation_block_index_].size -= *allocated; | 239 allocation_list_[current_allocation_block_index_].size -= *allocated; |
240 if (*allocated == current.size) { | 240 if (*allocated == current.size) { |
241 GetNextAllocationBlock(0); // This block is used up, get the next one. | 241 GetNextAllocationBlock(0); // This block is used up, get the next one. |
242 } | 242 } |
243 return current.start; | 243 return current.start; |
244 } | 244 } |
245 | 245 |
246 | 246 |
247 bool CodeRange::CommitRawMemory(Address start, size_t length) { | 247 bool CodeRange::CommitRawMemory(Address start, size_t length) { |
248 return isolate_->memory_allocator()->CommitMemory(start, length, EXECUTABLE); | 248 return isolate_->memory_allocator()->CommitMemory( |
| 249 start, length, VirtualMemory::EXECUTABLE); |
249 } | 250 } |
250 | 251 |
251 | 252 |
252 bool CodeRange::UncommitRawMemory(Address start, size_t length) { | 253 bool CodeRange::UncommitRawMemory(Address start, size_t length) { |
253 return code_range_->Uncommit(start, length); | 254 return code_range_->Uncommit(start, length); |
254 } | 255 } |
255 | 256 |
256 | 257 |
257 void CodeRange::FreeRawMemory(Address address, size_t length) { | 258 void CodeRange::FreeRawMemory(Address address, size_t length) { |
258 ASSERT(IsAddressAligned(address, MemoryChunk::kAlignment)); | 259 ASSERT(IsAddressAligned(address, MemoryChunk::kAlignment)); |
259 free_list_.Add(FreeBlock(address, length)); | 260 free_list_.Add(FreeBlock(address, length)); |
260 code_range_->Uncommit(address, length); | 261 bool result = code_range_->Uncommit(address, length); |
| 262 ASSERT(result); |
| 263 USE(result); |
261 } | 264 } |
262 | 265 |
263 | 266 |
264 void CodeRange::TearDown() { | 267 void CodeRange::TearDown() { |
265 delete code_range_; // Frees all memory in the virtual memory range. | 268 delete code_range_; // Frees all memory in the virtual memory range. |
266 code_range_ = NULL; | 269 code_range_ = NULL; |
267 free_list_.Free(); | 270 free_list_.Free(); |
268 allocation_list_.Free(); | 271 allocation_list_.Free(); |
269 } | 272 } |
270 | 273 |
(...skipping 30 matching lines...) Expand all Loading... |
301 ASSERT(size_ == 0); | 304 ASSERT(size_ == 0); |
302 // TODO(gc) this will be true again when we fix FreeMemory. | 305 // TODO(gc) this will be true again when we fix FreeMemory. |
303 // ASSERT(size_executable_ == 0); | 306 // ASSERT(size_executable_ == 0); |
304 capacity_ = 0; | 307 capacity_ = 0; |
305 capacity_executable_ = 0; | 308 capacity_executable_ = 0; |
306 } | 309 } |
307 | 310 |
308 | 311 |
309 bool MemoryAllocator::CommitMemory(Address base, | 312 bool MemoryAllocator::CommitMemory(Address base, |
310 size_t size, | 313 size_t size, |
311 Executability executable) { | 314 VirtualMemory::Executability executability) { |
312 if (!VirtualMemory::CommitRegion(base, size, executable == EXECUTABLE)) { | 315 if (!VirtualMemory::CommitRegion(base, size, executability)) { |
313 return false; | 316 return false; |
314 } | 317 } |
315 UpdateAllocatedSpaceLimits(base, base + size); | 318 UpdateAllocatedSpaceLimits(base, base + size); |
316 return true; | 319 return true; |
317 } | 320 } |
318 | 321 |
319 | 322 |
320 void MemoryAllocator::FreeMemory(VirtualMemory* reservation, | 323 void MemoryAllocator::FreeMemory(VirtualMemory* reservation, |
321 Executability executable) { | 324 VirtualMemory::Executability executability) { |
322 // TODO(gc) make code_range part of memory allocator? | 325 // TODO(gc) make code_range part of memory allocator? |
323 ASSERT(reservation->IsReserved()); | 326 ASSERT(reservation->IsReserved()); |
324 size_t size = reservation->size(); | 327 size_t size = reservation->size(); |
325 ASSERT(size_ >= size); | 328 ASSERT(size_ >= size); |
326 size_ -= size; | 329 size_ -= size; |
327 | 330 |
328 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); | 331 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); |
329 | 332 |
330 if (executable == EXECUTABLE) { | 333 if (executability == VirtualMemory::EXECUTABLE) { |
331 ASSERT(size_executable_ >= size); | 334 ASSERT(size_executable_ >= size); |
332 size_executable_ -= size; | 335 size_executable_ -= size; |
333 } | 336 } |
334 // Code which is part of the code-range does not have its own VirtualMemory. | 337 // Code which is part of the code-range does not have its own VirtualMemory. |
335 ASSERT(!isolate_->code_range()->contains( | 338 ASSERT(!isolate_->code_range()->contains( |
336 static_cast<Address>(reservation->address()))); | 339 static_cast<Address>(reservation->address()))); |
337 ASSERT(executable == NOT_EXECUTABLE || !isolate_->code_range()->exists()); | 340 ASSERT(executability == VirtualMemory::NOT_EXECUTABLE || |
| 341 !isolate_->code_range()->exists()); |
338 reservation->Release(); | 342 reservation->Release(); |
339 } | 343 } |
340 | 344 |
341 | 345 |
342 void MemoryAllocator::FreeMemory(Address base, | 346 void MemoryAllocator::FreeMemory(Address base, |
343 size_t size, | 347 size_t size, |
344 Executability executable) { | 348 VirtualMemory::Executability executability) { |
345 // TODO(gc) make code_range part of memory allocator? | 349 // TODO(gc) make code_range part of memory allocator? |
346 ASSERT(size_ >= size); | 350 ASSERT(size_ >= size); |
347 size_ -= size; | 351 size_ -= size; |
348 | 352 |
349 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); | 353 isolate_->counters()->memory_allocated()->Decrement(static_cast<int>(size)); |
350 | 354 |
351 if (executable == EXECUTABLE) { | 355 if (executability == VirtualMemory::EXECUTABLE) { |
352 ASSERT(size_executable_ >= size); | 356 ASSERT(size_executable_ >= size); |
353 size_executable_ -= size; | 357 size_executable_ -= size; |
354 } | 358 } |
355 if (isolate_->code_range()->contains(static_cast<Address>(base))) { | 359 if (isolate_->code_range()->contains(static_cast<Address>(base))) { |
356 ASSERT(executable == EXECUTABLE); | 360 ASSERT(executability == VirtualMemory::EXECUTABLE); |
357 isolate_->code_range()->FreeRawMemory(base, size); | 361 isolate_->code_range()->FreeRawMemory(base, size); |
358 } else { | 362 } else { |
359 ASSERT(executable == NOT_EXECUTABLE || !isolate_->code_range()->exists()); | 363 ASSERT(executability == VirtualMemory::NOT_EXECUTABLE || |
| 364 !isolate_->code_range()->exists()); |
360 bool result = VirtualMemory::ReleaseRegion(base, size); | 365 bool result = VirtualMemory::ReleaseRegion(base, size); |
361 USE(result); | 366 USE(result); |
362 ASSERT(result); | 367 ASSERT(result); |
363 } | 368 } |
364 } | 369 } |
365 | 370 |
366 | 371 |
367 Address MemoryAllocator::ReserveAlignedMemory(size_t size, | 372 Address MemoryAllocator::ReserveAlignedMemory(size_t size, |
368 size_t alignment, | 373 size_t alignment, |
369 VirtualMemory* controller) { | 374 VirtualMemory* controller) { |
370 VirtualMemory reservation(size, alignment); | 375 VirtualMemory reservation(size, alignment); |
371 | 376 |
372 if (!reservation.IsReserved()) return NULL; | 377 if (!reservation.IsReserved()) return NULL; |
373 size_ += reservation.size(); | 378 size_ += reservation.size(); |
374 Address base = RoundUp(static_cast<Address>(reservation.address()), | 379 Address base = RoundUp(static_cast<Address>(reservation.address()), |
375 alignment); | 380 alignment); |
376 controller->TakeControl(&reservation); | 381 controller->TakeControl(&reservation); |
377 return base; | 382 return base; |
378 } | 383 } |
379 | 384 |
380 | 385 |
381 Address MemoryAllocator::AllocateAlignedMemory(size_t reserve_size, | 386 Address MemoryAllocator::AllocateAlignedMemory( |
382 size_t commit_size, | 387 size_t reserve_size, |
383 size_t alignment, | 388 size_t commit_size, |
384 Executability executable, | 389 size_t alignment, |
385 VirtualMemory* controller) { | 390 VirtualMemory::Executability executability, |
| 391 VirtualMemory* controller) { |
386 ASSERT(commit_size <= reserve_size); | 392 ASSERT(commit_size <= reserve_size); |
387 VirtualMemory reservation; | 393 VirtualMemory reservation; |
388 Address base = ReserveAlignedMemory(reserve_size, alignment, &reservation); | 394 Address base = ReserveAlignedMemory(reserve_size, alignment, &reservation); |
389 if (base == NULL) return NULL; | 395 if (base == NULL) return NULL; |
390 | 396 |
391 if (executable == EXECUTABLE) { | 397 if (executability == VirtualMemory::EXECUTABLE) { |
392 if (!CommitExecutableMemory(&reservation, | 398 if (!CommitExecutableMemory(&reservation, |
393 base, | 399 base, |
394 commit_size, | 400 commit_size, |
395 reserve_size)) { | 401 reserve_size)) { |
396 base = NULL; | 402 base = NULL; |
397 } | 403 } |
398 } else { | 404 } else { |
399 if (reservation.Commit(base, commit_size, false)) { | 405 if (reservation.Commit(base, commit_size, VirtualMemory::NOT_EXECUTABLE)) { |
400 UpdateAllocatedSpaceLimits(base, base + commit_size); | 406 UpdateAllocatedSpaceLimits(base, base + commit_size); |
401 } else { | 407 } else { |
402 base = NULL; | 408 base = NULL; |
403 } | 409 } |
404 } | 410 } |
405 | 411 |
406 if (base == NULL) { | 412 if (base == NULL) { |
407 // Failed to commit the body. Release the mapping and any partially | 413 // Failed to commit the body. Release the mapping and any partially |
408 // commited regions inside it. | 414 // commited regions inside it. |
409 reservation.Release(); | 415 reservation.Release(); |
(...skipping 16 matching lines...) Expand all Loading... |
426 Address start, | 432 Address start, |
427 SemiSpace* semi_space) { | 433 SemiSpace* semi_space) { |
428 Address area_start = start + NewSpacePage::kObjectStartOffset; | 434 Address area_start = start + NewSpacePage::kObjectStartOffset; |
429 Address area_end = start + Page::kPageSize; | 435 Address area_end = start + Page::kPageSize; |
430 | 436 |
431 MemoryChunk* chunk = MemoryChunk::Initialize(heap, | 437 MemoryChunk* chunk = MemoryChunk::Initialize(heap, |
432 start, | 438 start, |
433 Page::kPageSize, | 439 Page::kPageSize, |
434 area_start, | 440 area_start, |
435 area_end, | 441 area_end, |
436 NOT_EXECUTABLE, | 442 VirtualMemory::NOT_EXECUTABLE, |
437 semi_space); | 443 semi_space); |
438 chunk->set_next_chunk(NULL); | 444 chunk->set_next_chunk(NULL); |
439 chunk->set_prev_chunk(NULL); | 445 chunk->set_prev_chunk(NULL); |
440 chunk->initialize_scan_on_scavenge(true); | 446 chunk->initialize_scan_on_scavenge(true); |
441 bool in_to_space = (semi_space->id() != kFromSpace); | 447 bool in_to_space = (semi_space->id() != kFromSpace); |
442 chunk->SetFlag(in_to_space ? MemoryChunk::IN_TO_SPACE | 448 chunk->SetFlag(in_to_space ? MemoryChunk::IN_TO_SPACE |
443 : MemoryChunk::IN_FROM_SPACE); | 449 : MemoryChunk::IN_FROM_SPACE); |
444 ASSERT(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE | 450 ASSERT(!chunk->IsFlagSet(in_to_space ? MemoryChunk::IN_FROM_SPACE |
445 : MemoryChunk::IN_TO_SPACE)); | 451 : MemoryChunk::IN_TO_SPACE)); |
446 NewSpacePage* page = static_cast<NewSpacePage*>(chunk); | 452 NewSpacePage* page = static_cast<NewSpacePage*>(chunk); |
(...skipping 10 matching lines...) Expand all Loading... |
457 // All real new-space pages will be in new-space. | 463 // All real new-space pages will be in new-space. |
458 SetFlags(0, ~0); | 464 SetFlags(0, ~0); |
459 } | 465 } |
460 | 466 |
461 | 467 |
462 MemoryChunk* MemoryChunk::Initialize(Heap* heap, | 468 MemoryChunk* MemoryChunk::Initialize(Heap* heap, |
463 Address base, | 469 Address base, |
464 size_t size, | 470 size_t size, |
465 Address area_start, | 471 Address area_start, |
466 Address area_end, | 472 Address area_end, |
467 Executability executable, | 473 VirtualMemory::Executability executability, |
468 Space* owner) { | 474 Space* owner) { |
469 MemoryChunk* chunk = FromAddress(base); | 475 MemoryChunk* chunk = FromAddress(base); |
470 | 476 |
471 ASSERT(base == chunk->address()); | 477 ASSERT(base == chunk->address()); |
472 | 478 |
473 chunk->heap_ = heap; | 479 chunk->heap_ = heap; |
474 chunk->size_ = size; | 480 chunk->size_ = size; |
475 chunk->area_start_ = area_start; | 481 chunk->area_start_ = area_start; |
476 chunk->area_end_ = area_end; | 482 chunk->area_end_ = area_end; |
477 chunk->flags_ = 0; | 483 chunk->flags_ = 0; |
(...skipping 11 matching lines...) Expand all Loading... |
489 chunk->available_in_huge_free_list_ = 0; | 495 chunk->available_in_huge_free_list_ = 0; |
490 chunk->non_available_small_blocks_ = 0; | 496 chunk->non_available_small_blocks_ = 0; |
491 chunk->ResetLiveBytes(); | 497 chunk->ResetLiveBytes(); |
492 Bitmap::Clear(chunk); | 498 Bitmap::Clear(chunk); |
493 chunk->initialize_scan_on_scavenge(false); | 499 chunk->initialize_scan_on_scavenge(false); |
494 chunk->SetFlag(WAS_SWEPT_PRECISELY); | 500 chunk->SetFlag(WAS_SWEPT_PRECISELY); |
495 | 501 |
496 ASSERT(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); | 502 ASSERT(OFFSET_OF(MemoryChunk, flags_) == kFlagsOffset); |
497 ASSERT(OFFSET_OF(MemoryChunk, live_byte_count_) == kLiveBytesOffset); | 503 ASSERT(OFFSET_OF(MemoryChunk, live_byte_count_) == kLiveBytesOffset); |
498 | 504 |
499 if (executable == EXECUTABLE) { | 505 if (executability == VirtualMemory::EXECUTABLE) { |
500 chunk->SetFlag(IS_EXECUTABLE); | 506 chunk->SetFlag(IS_EXECUTABLE); |
501 } | 507 } |
502 | 508 |
503 if (owner == heap->old_data_space()) { | 509 if (owner == heap->old_data_space()) { |
504 chunk->SetFlag(CONTAINS_ONLY_DATA); | 510 chunk->SetFlag(CONTAINS_ONLY_DATA); |
505 } | 511 } |
506 | 512 |
507 return chunk; | 513 return chunk; |
508 } | 514 } |
509 | 515 |
510 | 516 |
511 // Commit MemoryChunk area to the requested size. | 517 // Commit MemoryChunk area to the requested size. |
512 bool MemoryChunk::CommitArea(size_t requested) { | 518 bool MemoryChunk::CommitArea(size_t requested) { |
513 size_t guard_size = IsFlagSet(IS_EXECUTABLE) ? | 519 size_t guard_size = IsFlagSet(IS_EXECUTABLE) ? |
514 MemoryAllocator::CodePageGuardSize() : 0; | 520 MemoryAllocator::CodePageGuardSize() : 0; |
515 size_t header_size = area_start() - address() - guard_size; | 521 size_t header_size = area_start() - address() - guard_size; |
516 size_t commit_size = RoundUp(header_size + requested, OS::CommitPageSize()); | 522 size_t commit_size = RoundUp(header_size + requested, |
| 523 VirtualMemory::GetPageSize()); |
517 size_t committed_size = RoundUp(header_size + (area_end() - area_start()), | 524 size_t committed_size = RoundUp(header_size + (area_end() - area_start()), |
518 OS::CommitPageSize()); | 525 VirtualMemory::GetPageSize()); |
519 | 526 |
520 if (commit_size > committed_size) { | 527 if (commit_size > committed_size) { |
521 // Commit size should be less or equal than the reserved size. | 528 // Commit size should be less or equal than the reserved size. |
522 ASSERT(commit_size <= size() - 2 * guard_size); | 529 ASSERT(commit_size <= size() - 2 * guard_size); |
523 // Append the committed area. | 530 // Append the committed area. |
524 Address start = address() + committed_size + guard_size; | 531 Address start = address() + committed_size + guard_size; |
525 size_t length = commit_size - committed_size; | 532 size_t length = commit_size - committed_size; |
526 if (reservation_.IsReserved()) { | 533 if (reservation_.IsReserved()) { |
527 Executability executable = IsFlagSet(IS_EXECUTABLE) | 534 VirtualMemory::Executability executability = IsFlagSet(IS_EXECUTABLE) |
528 ? EXECUTABLE : NOT_EXECUTABLE; | 535 ? VirtualMemory::EXECUTABLE : VirtualMemory::NOT_EXECUTABLE; |
529 if (!heap()->isolate()->memory_allocator()->CommitMemory( | 536 if (!heap()->isolate()->memory_allocator()->CommitMemory( |
530 start, length, executable)) { | 537 start, length, executability)) { |
531 return false; | 538 return false; |
532 } | 539 } |
533 } else { | 540 } else { |
534 CodeRange* code_range = heap_->isolate()->code_range(); | 541 CodeRange* code_range = heap_->isolate()->code_range(); |
535 ASSERT(code_range->exists() && IsFlagSet(IS_EXECUTABLE)); | 542 ASSERT(code_range->exists() && IsFlagSet(IS_EXECUTABLE)); |
536 if (!code_range->CommitRawMemory(start, length)) return false; | 543 if (!code_range->CommitRawMemory(start, length)) return false; |
537 } | 544 } |
538 | 545 |
539 if (Heap::ShouldZapGarbage()) { | 546 if (Heap::ShouldZapGarbage()) { |
540 heap_->isolate()->memory_allocator()->ZapBlock(start, length); | 547 heap_->isolate()->memory_allocator()->ZapBlock(start, length); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 heap_->decrement_scan_on_scavenge_pages(); | 589 heap_->decrement_scan_on_scavenge_pages(); |
583 ClearFlag(SCAN_ON_SCAVENGE); | 590 ClearFlag(SCAN_ON_SCAVENGE); |
584 } | 591 } |
585 next_chunk_->prev_chunk_ = prev_chunk_; | 592 next_chunk_->prev_chunk_ = prev_chunk_; |
586 prev_chunk_->next_chunk_ = next_chunk_; | 593 prev_chunk_->next_chunk_ = next_chunk_; |
587 prev_chunk_ = NULL; | 594 prev_chunk_ = NULL; |
588 next_chunk_ = NULL; | 595 next_chunk_ = NULL; |
589 } | 596 } |
590 | 597 |
591 | 598 |
592 MemoryChunk* MemoryAllocator::AllocateChunk(intptr_t reserve_area_size, | 599 MemoryChunk* MemoryAllocator::AllocateChunk( |
593 intptr_t commit_area_size, | 600 intptr_t reserve_area_size, |
594 Executability executable, | 601 intptr_t commit_area_size, |
595 Space* owner) { | 602 VirtualMemory::Executability executability, |
| 603 Space* owner) { |
596 ASSERT(commit_area_size <= reserve_area_size); | 604 ASSERT(commit_area_size <= reserve_area_size); |
597 | 605 |
598 size_t chunk_size; | 606 size_t chunk_size; |
599 Heap* heap = isolate_->heap(); | 607 Heap* heap = isolate_->heap(); |
600 Address base = NULL; | 608 Address base = NULL; |
601 VirtualMemory reservation; | 609 VirtualMemory reservation; |
602 Address area_start = NULL; | 610 Address area_start = NULL; |
603 Address area_end = NULL; | 611 Address area_end = NULL; |
604 | 612 |
605 // | 613 // |
(...skipping 19 matching lines...) Expand all Loading... |
625 // | Header | | 633 // | Header | |
626 // +----------------------------+<- area_start_ (base + kObjectStartOffset) | 634 // +----------------------------+<- area_start_ (base + kObjectStartOffset) |
627 // | Area | | 635 // | Area | |
628 // +----------------------------+<- area_end_ (area_start + commit_area_size) | 636 // +----------------------------+<- area_end_ (area_start + commit_area_size) |
629 // | Committed but not used | | 637 // | Committed but not used | |
630 // +----------------------------+<- aligned at OS page boundary | 638 // +----------------------------+<- aligned at OS page boundary |
631 // | Reserved but not committed | | 639 // | Reserved but not committed | |
632 // +----------------------------+<- base + chunk_size | 640 // +----------------------------+<- base + chunk_size |
633 // | 641 // |
634 | 642 |
635 if (executable == EXECUTABLE) { | 643 if (executability == VirtualMemory::EXECUTABLE) { |
636 chunk_size = RoundUp(CodePageAreaStartOffset() + reserve_area_size, | 644 chunk_size = RoundUp(CodePageAreaStartOffset() + reserve_area_size, |
637 OS::CommitPageSize()) + CodePageGuardSize(); | 645 VirtualMemory::GetPageSize()) + CodePageGuardSize(); |
638 | 646 |
639 // Check executable memory limit. | 647 // Check executable memory limit. |
640 if (size_executable_ + chunk_size > capacity_executable_) { | 648 if (size_executable_ + chunk_size > capacity_executable_) { |
641 LOG(isolate_, | 649 LOG(isolate_, |
642 StringEvent("MemoryAllocator::AllocateRawMemory", | 650 StringEvent("MemoryAllocator::AllocateRawMemory", |
643 "V8 Executable Allocation capacity exceeded")); | 651 "V8 Executable Allocation capacity exceeded")); |
644 return NULL; | 652 return NULL; |
645 } | 653 } |
646 | 654 |
647 // Size of header (not executable) plus area (executable). | 655 // Size of header (not executable) plus area (executable). |
648 size_t commit_size = RoundUp(CodePageGuardStartOffset() + commit_area_size, | 656 size_t commit_size = RoundUp(CodePageGuardStartOffset() + commit_area_size, |
649 OS::CommitPageSize()); | 657 VirtualMemory::GetPageSize()); |
650 // Allocate executable memory either from code range or from the | 658 // Allocate executable memory either from code range or from the |
651 // OS. | 659 // OS. |
652 if (isolate_->code_range()->exists()) { | 660 if (isolate_->code_range()->exists()) { |
653 base = isolate_->code_range()->AllocateRawMemory(chunk_size, | 661 base = isolate_->code_range()->AllocateRawMemory(chunk_size, |
654 commit_size, | 662 commit_size, |
655 &chunk_size); | 663 &chunk_size); |
656 ASSERT(IsAligned(reinterpret_cast<intptr_t>(base), | 664 ASSERT(IsAligned(reinterpret_cast<intptr_t>(base), |
657 MemoryChunk::kAlignment)); | 665 MemoryChunk::kAlignment)); |
658 if (base == NULL) return NULL; | 666 if (base == NULL) return NULL; |
659 size_ += chunk_size; | 667 size_ += chunk_size; |
660 // Update executable memory size. | 668 // Update executable memory size. |
661 size_executable_ += chunk_size; | 669 size_executable_ += chunk_size; |
662 } else { | 670 } else { |
663 base = AllocateAlignedMemory(chunk_size, | 671 base = AllocateAlignedMemory(chunk_size, |
664 commit_size, | 672 commit_size, |
665 MemoryChunk::kAlignment, | 673 MemoryChunk::kAlignment, |
666 executable, | 674 executability, |
667 &reservation); | 675 &reservation); |
668 if (base == NULL) return NULL; | 676 if (base == NULL) return NULL; |
669 // Update executable memory size. | 677 // Update executable memory size. |
670 size_executable_ += reservation.size(); | 678 size_executable_ += reservation.size(); |
671 } | 679 } |
672 | 680 |
673 if (Heap::ShouldZapGarbage()) { | 681 if (Heap::ShouldZapGarbage()) { |
674 ZapBlock(base, CodePageGuardStartOffset()); | 682 ZapBlock(base, CodePageGuardStartOffset()); |
675 ZapBlock(base + CodePageAreaStartOffset(), commit_area_size); | 683 ZapBlock(base + CodePageAreaStartOffset(), commit_area_size); |
676 } | 684 } |
677 | 685 |
678 area_start = base + CodePageAreaStartOffset(); | 686 area_start = base + CodePageAreaStartOffset(); |
679 area_end = area_start + commit_area_size; | 687 area_end = area_start + commit_area_size; |
680 } else { | 688 } else { |
681 chunk_size = RoundUp(MemoryChunk::kObjectStartOffset + reserve_area_size, | 689 chunk_size = RoundUp(MemoryChunk::kObjectStartOffset + reserve_area_size, |
682 OS::CommitPageSize()); | 690 VirtualMemory::GetPageSize()); |
683 size_t commit_size = RoundUp(MemoryChunk::kObjectStartOffset + | 691 size_t commit_size = RoundUp( |
684 commit_area_size, OS::CommitPageSize()); | 692 MemoryChunk::kObjectStartOffset + commit_area_size, |
| 693 VirtualMemory::GetPageSize()); |
685 base = AllocateAlignedMemory(chunk_size, | 694 base = AllocateAlignedMemory(chunk_size, |
686 commit_size, | 695 commit_size, |
687 MemoryChunk::kAlignment, | 696 MemoryChunk::kAlignment, |
688 executable, | 697 executability, |
689 &reservation); | 698 &reservation); |
690 | 699 |
691 if (base == NULL) return NULL; | 700 if (base == NULL) return NULL; |
692 | 701 |
693 if (Heap::ShouldZapGarbage()) { | 702 if (Heap::ShouldZapGarbage()) { |
694 ZapBlock(base, Page::kObjectStartOffset + commit_area_size); | 703 ZapBlock(base, Page::kObjectStartOffset + commit_area_size); |
695 } | 704 } |
696 | 705 |
697 area_start = base + Page::kObjectStartOffset; | 706 area_start = base + Page::kObjectStartOffset; |
698 area_end = area_start + commit_area_size; | 707 area_end = area_start + commit_area_size; |
699 } | 708 } |
700 | 709 |
701 // Use chunk_size for statistics and callbacks because we assume that they | 710 // Use chunk_size for statistics and callbacks because we assume that they |
702 // treat reserved but not-yet committed memory regions of chunks as allocated. | 711 // treat reserved but not-yet committed memory regions of chunks as allocated. |
703 isolate_->counters()->memory_allocated()-> | 712 isolate_->counters()->memory_allocated()-> |
704 Increment(static_cast<int>(chunk_size)); | 713 Increment(static_cast<int>(chunk_size)); |
705 | 714 |
706 LOG(isolate_, NewEvent("MemoryChunk", base, chunk_size)); | 715 LOG(isolate_, NewEvent("MemoryChunk", base, chunk_size)); |
707 if (owner != NULL) { | 716 if (owner != NULL) { |
708 ObjectSpace space = static_cast<ObjectSpace>(1 << owner->identity()); | 717 ObjectSpace space = static_cast<ObjectSpace>(1 << owner->identity()); |
709 PerformAllocationCallback(space, kAllocationActionAllocate, chunk_size); | 718 PerformAllocationCallback(space, kAllocationActionAllocate, chunk_size); |
710 } | 719 } |
711 | 720 |
712 MemoryChunk* result = MemoryChunk::Initialize(heap, | 721 MemoryChunk* result = MemoryChunk::Initialize(heap, |
713 base, | 722 base, |
714 chunk_size, | 723 chunk_size, |
715 area_start, | 724 area_start, |
716 area_end, | 725 area_end, |
717 executable, | 726 executability, |
718 owner); | 727 owner); |
719 result->set_reserved_memory(&reservation); | 728 result->set_reserved_memory(&reservation); |
720 return result; | 729 return result; |
721 } | 730 } |
722 | 731 |
723 | 732 |
724 void Page::ResetFreeListStatistics() { | 733 void Page::ResetFreeListStatistics() { |
725 non_available_small_blocks_ = 0; | 734 non_available_small_blocks_ = 0; |
726 available_in_small_free_list_ = 0; | 735 available_in_small_free_list_ = 0; |
727 available_in_medium_free_list_ = 0; | 736 available_in_medium_free_list_ = 0; |
728 available_in_large_free_list_ = 0; | 737 available_in_large_free_list_ = 0; |
729 available_in_huge_free_list_ = 0; | 738 available_in_huge_free_list_ = 0; |
730 } | 739 } |
731 | 740 |
732 | 741 |
733 Page* MemoryAllocator::AllocatePage(intptr_t size, | 742 Page* MemoryAllocator::AllocatePage( |
734 PagedSpace* owner, | 743 intptr_t size, |
735 Executability executable) { | 744 PagedSpace* owner, |
736 MemoryChunk* chunk = AllocateChunk(size, size, executable, owner); | 745 VirtualMemory::Executability executability) { |
| 746 MemoryChunk* chunk = AllocateChunk(size, size, executability, owner); |
737 | 747 |
738 if (chunk == NULL) return NULL; | 748 if (chunk == NULL) return NULL; |
739 | 749 |
740 return Page::Initialize(isolate_->heap(), chunk, executable, owner); | 750 return Page::Initialize(isolate_->heap(), chunk, executability, owner); |
741 } | 751 } |
742 | 752 |
743 | 753 |
744 LargePage* MemoryAllocator::AllocateLargePage(intptr_t object_size, | 754 LargePage* MemoryAllocator::AllocateLargePage( |
745 Space* owner, | 755 intptr_t object_size, |
746 Executability executable) { | 756 Space* owner, |
| 757 VirtualMemory::Executability executability) { |
747 MemoryChunk* chunk = AllocateChunk(object_size, | 758 MemoryChunk* chunk = AllocateChunk(object_size, |
748 object_size, | 759 object_size, |
749 executable, | 760 executability, |
750 owner); | 761 owner); |
751 if (chunk == NULL) return NULL; | 762 if (chunk == NULL) return NULL; |
752 return LargePage::Initialize(isolate_->heap(), chunk); | 763 return LargePage::Initialize(isolate_->heap(), chunk); |
753 } | 764 } |
754 | 765 |
755 | 766 |
756 void MemoryAllocator::Free(MemoryChunk* chunk) { | 767 void MemoryAllocator::Free(MemoryChunk* chunk) { |
757 LOG(isolate_, DeleteEvent("MemoryChunk", chunk)); | 768 LOG(isolate_, DeleteEvent("MemoryChunk", chunk)); |
758 if (chunk->owner() != NULL) { | 769 if (chunk->owner() != NULL) { |
759 ObjectSpace space = | 770 ObjectSpace space = |
760 static_cast<ObjectSpace>(1 << chunk->owner()->identity()); | 771 static_cast<ObjectSpace>(1 << chunk->owner()->identity()); |
761 PerformAllocationCallback(space, kAllocationActionFree, chunk->size()); | 772 PerformAllocationCallback(space, kAllocationActionFree, chunk->size()); |
762 } | 773 } |
763 | 774 |
764 isolate_->heap()->RememberUnmappedPage( | 775 isolate_->heap()->RememberUnmappedPage( |
765 reinterpret_cast<Address>(chunk), chunk->IsEvacuationCandidate()); | 776 reinterpret_cast<Address>(chunk), chunk->IsEvacuationCandidate()); |
766 | 777 |
767 delete chunk->slots_buffer(); | 778 delete chunk->slots_buffer(); |
768 delete chunk->skip_list(); | 779 delete chunk->skip_list(); |
769 | 780 |
770 VirtualMemory* reservation = chunk->reserved_memory(); | 781 VirtualMemory* reservation = chunk->reserved_memory(); |
771 if (reservation->IsReserved()) { | 782 if (reservation->IsReserved()) { |
772 FreeMemory(reservation, chunk->executable()); | 783 FreeMemory(reservation, chunk->executability()); |
773 } else { | 784 } else { |
774 FreeMemory(chunk->address(), | 785 FreeMemory(chunk->address(), |
775 chunk->size(), | 786 chunk->size(), |
776 chunk->executable()); | 787 chunk->executability()); |
777 } | 788 } |
778 } | 789 } |
779 | 790 |
780 | 791 |
781 bool MemoryAllocator::CommitBlock(Address start, | 792 bool MemoryAllocator::CommitBlock(Address start, |
782 size_t size, | 793 size_t size, |
783 Executability executable) { | 794 VirtualMemory::Executability executability) { |
784 if (!CommitMemory(start, size, executable)) return false; | 795 if (!CommitMemory(start, size, executability)) return false; |
785 | 796 |
786 if (Heap::ShouldZapGarbage()) { | 797 if (Heap::ShouldZapGarbage()) { |
787 ZapBlock(start, size); | 798 ZapBlock(start, size); |
788 } | 799 } |
789 | 800 |
790 isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size)); | 801 isolate_->counters()->memory_allocated()->Increment(static_cast<int>(size)); |
791 return true; | 802 return true; |
792 } | 803 } |
793 | 804 |
794 | 805 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 ", used: %" V8_PTR_PREFIX "d" | 870 ", used: %" V8_PTR_PREFIX "d" |
860 ", available: %%%d\n\n", | 871 ", available: %%%d\n\n", |
861 capacity_, size_, static_cast<int>(pct*100)); | 872 capacity_, size_, static_cast<int>(pct*100)); |
862 } | 873 } |
863 #endif | 874 #endif |
864 | 875 |
865 | 876 |
866 int MemoryAllocator::CodePageGuardStartOffset() { | 877 int MemoryAllocator::CodePageGuardStartOffset() { |
867 // We are guarding code pages: the first OS page after the header | 878 // We are guarding code pages: the first OS page after the header |
868 // will be protected as non-writable. | 879 // will be protected as non-writable. |
869 return RoundUp(Page::kObjectStartOffset, OS::CommitPageSize()); | 880 return RoundUp(Page::kObjectStartOffset, VirtualMemory::GetPageSize()); |
870 } | 881 } |
871 | 882 |
872 | 883 |
873 int MemoryAllocator::CodePageGuardSize() { | 884 int MemoryAllocator::CodePageGuardSize() { |
874 return static_cast<int>(OS::CommitPageSize()); | 885 return static_cast<int>(VirtualMemory::GetPageSize()); |
875 } | 886 } |
876 | 887 |
877 | 888 |
878 int MemoryAllocator::CodePageAreaStartOffset() { | 889 int MemoryAllocator::CodePageAreaStartOffset() { |
879 // We are guarding code pages: the first OS page after the header | 890 // We are guarding code pages: the first OS page after the header |
880 // will be protected as non-writable. | 891 // will be protected as non-writable. |
881 return CodePageGuardStartOffset() + CodePageGuardSize(); | 892 return CodePageGuardStartOffset() + CodePageGuardSize(); |
882 } | 893 } |
883 | 894 |
884 | 895 |
885 int MemoryAllocator::CodePageAreaEndOffset() { | 896 int MemoryAllocator::CodePageAreaEndOffset() { |
886 // We are guarding code pages: the last OS page will be protected as | 897 // We are guarding code pages: the last OS page will be protected as |
887 // non-writable. | 898 // non-writable. |
888 return Page::kPageSize - static_cast<int>(OS::CommitPageSize()); | 899 return Page::kPageSize - static_cast<int>(VirtualMemory::GetPageSize()); |
889 } | 900 } |
890 | 901 |
891 | 902 |
892 bool MemoryAllocator::CommitExecutableMemory(VirtualMemory* vm, | 903 bool MemoryAllocator::CommitExecutableMemory(VirtualMemory* vm, |
893 Address start, | 904 Address start, |
894 size_t commit_size, | 905 size_t commit_size, |
895 size_t reserved_size) { | 906 size_t reserved_size) { |
896 // Commit page header (not executable). | 907 // Commit page header (not executable). |
897 if (!vm->Commit(start, | 908 if (!vm->Commit(start, |
898 CodePageGuardStartOffset(), | 909 CodePageGuardStartOffset(), |
899 false)) { | 910 VirtualMemory::NOT_EXECUTABLE)) { |
900 return false; | 911 return false; |
901 } | 912 } |
902 | 913 |
903 // Create guard page after the header. | 914 // Create guard page after the header. |
904 if (!vm->Guard(start + CodePageGuardStartOffset())) { | 915 if (!vm->Guard(start + CodePageGuardStartOffset(), |
| 916 VirtualMemory::GetPageSize())) { |
905 return false; | 917 return false; |
906 } | 918 } |
907 | 919 |
908 // Commit page body (executable). | 920 // Commit page body (executable). |
909 if (!vm->Commit(start + CodePageAreaStartOffset(), | 921 if (!vm->Commit(start + CodePageAreaStartOffset(), |
910 commit_size - CodePageGuardStartOffset(), | 922 commit_size - CodePageGuardStartOffset(), |
911 true)) { | 923 VirtualMemory::EXECUTABLE)) { |
912 return false; | 924 return false; |
913 } | 925 } |
914 | 926 |
915 // Create guard page before the end. | 927 // Create guard page before the end. |
916 if (!vm->Guard(start + reserved_size - CodePageGuardSize())) { | 928 if (!vm->Guard(start + reserved_size - CodePageGuardSize(), |
| 929 VirtualMemory::GetPageSize())) { |
917 return false; | 930 return false; |
918 } | 931 } |
919 | 932 |
920 UpdateAllocatedSpaceLimits(start, | 933 UpdateAllocatedSpaceLimits(start, |
921 start + CodePageAreaStartOffset() + | 934 start + CodePageAreaStartOffset() + |
922 commit_size - CodePageGuardStartOffset()); | 935 commit_size - CodePageGuardStartOffset()); |
923 return true; | 936 return true; |
924 } | 937 } |
925 | 938 |
926 | 939 |
927 // ----------------------------------------------------------------------------- | 940 // ----------------------------------------------------------------------------- |
928 // MemoryChunk implementation | 941 // MemoryChunk implementation |
929 | 942 |
930 void MemoryChunk::IncrementLiveBytesFromMutator(Address address, int by) { | 943 void MemoryChunk::IncrementLiveBytesFromMutator(Address address, int by) { |
931 MemoryChunk* chunk = MemoryChunk::FromAddress(address); | 944 MemoryChunk* chunk = MemoryChunk::FromAddress(address); |
932 if (!chunk->InNewSpace() && !static_cast<Page*>(chunk)->WasSwept()) { | 945 if (!chunk->InNewSpace() && !static_cast<Page*>(chunk)->WasSwept()) { |
933 static_cast<PagedSpace*>(chunk->owner())->IncrementUnsweptFreeBytes(-by); | 946 static_cast<PagedSpace*>(chunk->owner())->IncrementUnsweptFreeBytes(-by); |
934 } | 947 } |
935 chunk->IncrementLiveBytes(by); | 948 chunk->IncrementLiveBytes(by); |
936 } | 949 } |
937 | 950 |
938 | 951 |
939 // ----------------------------------------------------------------------------- | 952 // ----------------------------------------------------------------------------- |
940 // PagedSpace implementation | 953 // PagedSpace implementation |
941 | 954 |
942 PagedSpace::PagedSpace(Heap* heap, | 955 PagedSpace::PagedSpace(Heap* heap, |
943 intptr_t max_capacity, | 956 intptr_t max_capacity, |
944 AllocationSpace id, | 957 AllocationSpace id, |
945 Executability executable) | 958 VirtualMemory::Executability executability) |
946 : Space(heap, id, executable), | 959 : Space(heap, id, executability), |
947 free_list_(this), | 960 free_list_(this), |
948 was_swept_conservatively_(false), | 961 was_swept_conservatively_(false), |
949 first_unswept_page_(Page::FromAddress(NULL)), | 962 first_unswept_page_(Page::FromAddress(NULL)), |
950 unswept_free_bytes_(0) { | 963 unswept_free_bytes_(0) { |
951 if (id == CODE_SPACE) { | 964 if (id == CODE_SPACE) { |
952 area_size_ = heap->isolate()->memory_allocator()-> | 965 area_size_ = heap->isolate()->memory_allocator()-> |
953 CodePageAreaSize(); | 966 CodePageAreaSize(); |
954 } else { | 967 } else { |
955 area_size_ = Page::kPageSize - Page::kObjectStartOffset; | 968 area_size_ = Page::kPageSize - Page::kObjectStartOffset; |
956 } | 969 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1034 bool PagedSpace::Expand() { | 1047 bool PagedSpace::Expand() { |
1035 if (!CanExpand()) return false; | 1048 if (!CanExpand()) return false; |
1036 | 1049 |
1037 intptr_t size = AreaSize(); | 1050 intptr_t size = AreaSize(); |
1038 | 1051 |
1039 if (anchor_.next_page() == &anchor_) { | 1052 if (anchor_.next_page() == &anchor_) { |
1040 size = SizeOfFirstPage(); | 1053 size = SizeOfFirstPage(); |
1041 } | 1054 } |
1042 | 1055 |
1043 Page* p = heap()->isolate()->memory_allocator()->AllocatePage( | 1056 Page* p = heap()->isolate()->memory_allocator()->AllocatePage( |
1044 size, this, executable()); | 1057 size, this, executability()); |
1045 if (p == NULL) return false; | 1058 if (p == NULL) return false; |
1046 | 1059 |
1047 ASSERT(Capacity() <= max_capacity_); | 1060 ASSERT(Capacity() <= max_capacity_); |
1048 | 1061 |
1049 p->InsertAfter(anchor_.prev_page()); | 1062 p->InsertAfter(anchor_.prev_page()); |
1050 | 1063 |
1051 return true; | 1064 return true; |
1052 } | 1065 } |
1053 | 1066 |
1054 | 1067 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1281 start_ = NULL; | 1294 start_ = NULL; |
1282 allocation_info_.top = NULL; | 1295 allocation_info_.top = NULL; |
1283 allocation_info_.limit = NULL; | 1296 allocation_info_.limit = NULL; |
1284 | 1297 |
1285 to_space_.TearDown(); | 1298 to_space_.TearDown(); |
1286 from_space_.TearDown(); | 1299 from_space_.TearDown(); |
1287 | 1300 |
1288 LOG(heap()->isolate(), DeleteEvent("InitialChunk", chunk_base_)); | 1301 LOG(heap()->isolate(), DeleteEvent("InitialChunk", chunk_base_)); |
1289 | 1302 |
1290 ASSERT(reservation_.IsReserved()); | 1303 ASSERT(reservation_.IsReserved()); |
1291 heap()->isolate()->memory_allocator()->FreeMemory(&reservation_, | 1304 heap()->isolate()->memory_allocator()->FreeMemory( |
1292 NOT_EXECUTABLE); | 1305 &reservation_, VirtualMemory::NOT_EXECUTABLE); |
1293 chunk_base_ = NULL; | 1306 chunk_base_ = NULL; |
1294 chunk_size_ = 0; | 1307 chunk_size_ = 0; |
1295 } | 1308 } |
1296 | 1309 |
1297 | 1310 |
1298 void NewSpace::Flip() { | 1311 void NewSpace::Flip() { |
1299 SemiSpace::Swap(&from_space_, &to_space_); | 1312 SemiSpace::Swap(&from_space_, &to_space_); |
1300 } | 1313 } |
1301 | 1314 |
1302 | 1315 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1517 } | 1530 } |
1518 | 1531 |
1519 | 1532 |
1520 bool SemiSpace::Commit() { | 1533 bool SemiSpace::Commit() { |
1521 ASSERT(!is_committed()); | 1534 ASSERT(!is_committed()); |
1522 int pages = capacity_ / Page::kPageSize; | 1535 int pages = capacity_ / Page::kPageSize; |
1523 Address end = start_ + maximum_capacity_; | 1536 Address end = start_ + maximum_capacity_; |
1524 Address start = end - pages * Page::kPageSize; | 1537 Address start = end - pages * Page::kPageSize; |
1525 if (!heap()->isolate()->memory_allocator()->CommitBlock(start, | 1538 if (!heap()->isolate()->memory_allocator()->CommitBlock(start, |
1526 capacity_, | 1539 capacity_, |
1527 executable())) { | 1540 executability())) { |
1528 return false; | 1541 return false; |
1529 } | 1542 } |
1530 | 1543 |
1531 NewSpacePage* page = anchor(); | 1544 NewSpacePage* page = anchor(); |
1532 for (int i = 1; i <= pages; i++) { | 1545 for (int i = 1; i <= pages; i++) { |
1533 NewSpacePage* new_page = | 1546 NewSpacePage* new_page = |
1534 NewSpacePage::Initialize(heap(), end - i * Page::kPageSize, this); | 1547 NewSpacePage::Initialize(heap(), end - i * Page::kPageSize, this); |
1535 new_page->InsertAfter(page); | 1548 new_page->InsertAfter(page); |
1536 page = new_page; | 1549 page = new_page; |
1537 } | 1550 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1574 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); | 1587 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); |
1575 ASSERT(new_capacity <= maximum_capacity_); | 1588 ASSERT(new_capacity <= maximum_capacity_); |
1576 ASSERT(new_capacity > capacity_); | 1589 ASSERT(new_capacity > capacity_); |
1577 int pages_before = capacity_ / Page::kPageSize; | 1590 int pages_before = capacity_ / Page::kPageSize; |
1578 int pages_after = new_capacity / Page::kPageSize; | 1591 int pages_after = new_capacity / Page::kPageSize; |
1579 | 1592 |
1580 Address end = start_ + maximum_capacity_; | 1593 Address end = start_ + maximum_capacity_; |
1581 Address start = end - new_capacity; | 1594 Address start = end - new_capacity; |
1582 size_t delta = new_capacity - capacity_; | 1595 size_t delta = new_capacity - capacity_; |
1583 | 1596 |
1584 ASSERT(IsAligned(delta, OS::AllocateAlignment())); | 1597 ASSERT(IsAligned(delta, VirtualMemory::GetAllocationGranularity())); |
1585 if (!heap()->isolate()->memory_allocator()->CommitBlock( | 1598 if (!heap()->isolate()->memory_allocator()->CommitBlock( |
1586 start, delta, executable())) { | 1599 start, delta, executability())) { |
1587 return false; | 1600 return false; |
1588 } | 1601 } |
1589 capacity_ = new_capacity; | 1602 capacity_ = new_capacity; |
1590 NewSpacePage* last_page = anchor()->prev_page(); | 1603 NewSpacePage* last_page = anchor()->prev_page(); |
1591 ASSERT(last_page != anchor()); | 1604 ASSERT(last_page != anchor()); |
1592 for (int i = pages_before + 1; i <= pages_after; i++) { | 1605 for (int i = pages_before + 1; i <= pages_after; i++) { |
1593 Address page_address = end - i * Page::kPageSize; | 1606 Address page_address = end - i * Page::kPageSize; |
1594 NewSpacePage* new_page = NewSpacePage::Initialize(heap(), | 1607 NewSpacePage* new_page = NewSpacePage::Initialize(heap(), |
1595 page_address, | 1608 page_address, |
1596 this); | 1609 this); |
(...skipping 12 matching lines...) Expand all Loading... |
1609 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); | 1622 ASSERT((new_capacity & Page::kPageAlignmentMask) == 0); |
1610 ASSERT(new_capacity >= initial_capacity_); | 1623 ASSERT(new_capacity >= initial_capacity_); |
1611 ASSERT(new_capacity < capacity_); | 1624 ASSERT(new_capacity < capacity_); |
1612 if (is_committed()) { | 1625 if (is_committed()) { |
1613 // Semispaces grow backwards from the end of their allocated capacity, | 1626 // Semispaces grow backwards from the end of their allocated capacity, |
1614 // so we find the before and after start addresses relative to the | 1627 // so we find the before and after start addresses relative to the |
1615 // end of the space. | 1628 // end of the space. |
1616 Address space_end = start_ + maximum_capacity_; | 1629 Address space_end = start_ + maximum_capacity_; |
1617 Address old_start = space_end - capacity_; | 1630 Address old_start = space_end - capacity_; |
1618 size_t delta = capacity_ - new_capacity; | 1631 size_t delta = capacity_ - new_capacity; |
1619 ASSERT(IsAligned(delta, OS::AllocateAlignment())); | 1632 ASSERT(IsAligned(delta, VirtualMemory::GetAllocationGranularity())); |
1620 | 1633 |
1621 MemoryAllocator* allocator = heap()->isolate()->memory_allocator(); | 1634 MemoryAllocator* allocator = heap()->isolate()->memory_allocator(); |
1622 if (!allocator->UncommitBlock(old_start, delta)) { | 1635 if (!allocator->UncommitBlock(old_start, delta)) { |
1623 return false; | 1636 return false; |
1624 } | 1637 } |
1625 | 1638 |
1626 int pages_after = new_capacity / Page::kPageSize; | 1639 int pages_after = new_capacity / Page::kPageSize; |
1627 NewSpacePage* new_last_page = | 1640 NewSpacePage* new_last_page = |
1628 NewSpacePage::FromAddress(space_end - pages_after * Page::kPageSize); | 1641 NewSpacePage::FromAddress(space_end - pages_after * Page::kPageSize); |
1629 new_last_page->set_next_page(anchor()); | 1642 new_last_page->set_next_page(anchor()); |
(...skipping 1287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2917 // ----------------------------------------------------------------------------- | 2930 // ----------------------------------------------------------------------------- |
2918 // LargeObjectSpace | 2931 // LargeObjectSpace |
2919 static bool ComparePointers(void* key1, void* key2) { | 2932 static bool ComparePointers(void* key1, void* key2) { |
2920 return key1 == key2; | 2933 return key1 == key2; |
2921 } | 2934 } |
2922 | 2935 |
2923 | 2936 |
2924 LargeObjectSpace::LargeObjectSpace(Heap* heap, | 2937 LargeObjectSpace::LargeObjectSpace(Heap* heap, |
2925 intptr_t max_capacity, | 2938 intptr_t max_capacity, |
2926 AllocationSpace id) | 2939 AllocationSpace id) |
2927 : Space(heap, id, NOT_EXECUTABLE), // Managed on a per-allocation basis | 2940 // Managed on a per-allocation basis |
| 2941 : Space(heap, id, VirtualMemory::NOT_EXECUTABLE), |
2928 max_capacity_(max_capacity), | 2942 max_capacity_(max_capacity), |
2929 first_page_(NULL), | 2943 first_page_(NULL), |
2930 size_(0), | 2944 size_(0), |
2931 page_count_(0), | 2945 page_count_(0), |
2932 objects_size_(0), | 2946 objects_size_(0), |
2933 chunk_map_(ComparePointers, 1024) {} | 2947 chunk_map_(ComparePointers, 1024) {} |
2934 | 2948 |
2935 | 2949 |
2936 bool LargeObjectSpace::SetUp() { | 2950 bool LargeObjectSpace::SetUp() { |
2937 first_page_ = NULL; | 2951 first_page_ = NULL; |
(...skipping 13 matching lines...) Expand all Loading... |
2951 | 2965 |
2952 ObjectSpace space = static_cast<ObjectSpace>(1 << identity()); | 2966 ObjectSpace space = static_cast<ObjectSpace>(1 << identity()); |
2953 heap()->isolate()->memory_allocator()->PerformAllocationCallback( | 2967 heap()->isolate()->memory_allocator()->PerformAllocationCallback( |
2954 space, kAllocationActionFree, page->size()); | 2968 space, kAllocationActionFree, page->size()); |
2955 heap()->isolate()->memory_allocator()->Free(page); | 2969 heap()->isolate()->memory_allocator()->Free(page); |
2956 } | 2970 } |
2957 SetUp(); | 2971 SetUp(); |
2958 } | 2972 } |
2959 | 2973 |
2960 | 2974 |
2961 MaybeObject* LargeObjectSpace::AllocateRaw(int object_size, | 2975 MaybeObject* LargeObjectSpace::AllocateRaw( |
2962 Executability executable) { | 2976 int object_size, VirtualMemory::Executability executability) { |
2963 // Check if we want to force a GC before growing the old space further. | 2977 // Check if we want to force a GC before growing the old space further. |
2964 // If so, fail the allocation. | 2978 // If so, fail the allocation. |
2965 if (!heap()->always_allocate() && | 2979 if (!heap()->always_allocate() && |
2966 heap()->OldGenerationAllocationLimitReached()) { | 2980 heap()->OldGenerationAllocationLimitReached()) { |
2967 return Failure::RetryAfterGC(identity()); | 2981 return Failure::RetryAfterGC(identity()); |
2968 } | 2982 } |
2969 | 2983 |
2970 if (Size() + object_size > max_capacity_) { | 2984 if (Size() + object_size > max_capacity_) { |
2971 return Failure::RetryAfterGC(identity()); | 2985 return Failure::RetryAfterGC(identity()); |
2972 } | 2986 } |
2973 | 2987 |
2974 LargePage* page = heap()->isolate()->memory_allocator()-> | 2988 LargePage* page = heap()->isolate()->memory_allocator()-> |
2975 AllocateLargePage(object_size, this, executable); | 2989 AllocateLargePage(object_size, this, executability); |
2976 if (page == NULL) return Failure::RetryAfterGC(identity()); | 2990 if (page == NULL) return Failure::RetryAfterGC(identity()); |
2977 ASSERT(page->area_size() >= object_size); | 2991 ASSERT(page->area_size() >= object_size); |
2978 | 2992 |
2979 size_ += static_cast<int>(page->size()); | 2993 size_ += static_cast<int>(page->size()); |
2980 objects_size_ += object_size; | 2994 objects_size_ += object_size; |
2981 page_count_++; | 2995 page_count_++; |
2982 page->set_next_page(first_page_); | 2996 page->set_next_page(first_page_); |
2983 first_page_ = page; | 2997 first_page_ = page; |
2984 | 2998 |
2985 // Register all MemoryChunk::kAlignment-aligned chunks covered by | 2999 // Register all MemoryChunk::kAlignment-aligned chunks covered by |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3221 object->ShortPrint(); | 3235 object->ShortPrint(); |
3222 PrintF("\n"); | 3236 PrintF("\n"); |
3223 } | 3237 } |
3224 printf(" --------------------------------------\n"); | 3238 printf(" --------------------------------------\n"); |
3225 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); | 3239 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); |
3226 } | 3240 } |
3227 | 3241 |
3228 #endif // DEBUG | 3242 #endif // DEBUG |
3229 | 3243 |
3230 } } // namespace v8::internal | 3244 } } // namespace v8::internal |
OLD | NEW |