Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/pages.h" | 5 #include "vm/pages.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/compiler_stats.h" | 8 #include "vm/compiler_stats.h" |
| 9 #include "vm/gc_marker.h" | 9 #include "vm/gc_marker.h" |
| 10 #include "vm/gc_sweeper.h" | 10 #include "vm/gc_sweeper.h" |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 408 // TODO(koda): Control growth. | 408 // TODO(koda): Control growth. |
| 409 } | 409 } |
| 410 | 410 |
| 411 | 411 |
| 412 void PageSpace::FreeExternal(intptr_t size) { | 412 void PageSpace::FreeExternal(intptr_t size) { |
| 413 intptr_t size_in_words = size >> kWordSizeLog2; | 413 intptr_t size_in_words = size >> kWordSizeLog2; |
| 414 usage_.external_in_words -= size_in_words; | 414 usage_.external_in_words -= size_in_words; |
| 415 } | 415 } |
| 416 | 416 |
| 417 | 417 |
| 418 // Provides exclusive access to the pages, and ensures they are walkable. | 418 // Provides exclusive access to all pages, and ensures they are walkable. |
| 419 class ExclusivePageIterator : ValueObject { | 419 class ExclusivePageIterator : ValueObject { |
| 420 public: | 420 public: |
| 421 explicit ExclusivePageIterator(const PageSpace* space) | 421 explicit ExclusivePageIterator(const PageSpace* space) |
| 422 : space_(space), ml_(space->pages_lock_) { | 422 : space_(space), ml_(space->pages_lock_) { |
| 423 space_->MakeIterable(); | 423 space_->MakeIterable(); |
| 424 page_ = space_->pages_; | 424 page_ = space_->pages_; |
| 425 if (page_ == NULL) { | 425 if (page_ == NULL) { |
| 426 page_ = space_->exec_pages_; | 426 page_ = space_->exec_pages_; |
| 427 if (page_ == NULL) { | 427 if (page_ == NULL) { |
| 428 page_ = space_->large_pages_; | 428 page_ = space_->large_pages_; |
| 429 } | 429 } |
| 430 } | 430 } |
| 431 } | 431 } |
| 432 HeapPage* page() const { return page_; } | 432 HeapPage* page() const { return page_; } |
| 433 bool Done() const { return page_ == NULL; } | 433 bool Done() const { return page_ == NULL; } |
| 434 void Advance() { | 434 void Advance() { |
| 435 ASSERT(!Done()); | 435 ASSERT(!Done()); |
| 436 page_ = space_->NextPageAnySize(page_); | 436 page_ = space_->NextPageAnySize(page_); |
| 437 } | 437 } |
| 438 private: | 438 private: |
| 439 const PageSpace* space_; | 439 const PageSpace* space_; |
| 440 MutexLocker ml_; | 440 MutexLocker ml_; |
| 441 NoGCScope no_gc; | 441 NoGCScope no_gc; |
| 442 HeapPage* page_; | 442 HeapPage* page_; |
| 443 }; | 443 }; |
| 444 | 444 |
| 445 | 445 |
| 446 // Provides exclusive access to code pages, and ensures they are walkable. | |
|
Ivan Posva
2015/01/07 21:35:04
Please make a note in the comment that this iterat
Cutch
2015/01/07 21:38:03
Done.
| |
| 447 class ExclusiveCodePageIterator : ValueObject { | |
| 448 public: | |
| 449 explicit ExclusiveCodePageIterator(const PageSpace* space) | |
| 450 : space_(space), ml_(space->pages_lock_) { | |
| 451 space_->MakeIterable(); | |
| 452 page_ = space_->exec_pages_; | |
| 453 } | |
| 454 HeapPage* page() const { return page_; } | |
| 455 bool Done() const { return page_ == NULL; } | |
| 456 void Advance() { | |
| 457 ASSERT(!Done()); | |
| 458 page_ = page_->next(); | |
| 459 } | |
| 460 private: | |
| 461 const PageSpace* space_; | |
| 462 MutexLocker ml_; | |
| 463 NoGCScope no_gc; | |
| 464 HeapPage* page_; | |
| 465 }; | |
| 466 | |
| 467 | |
| 468 // Provides exclusive access to large pages, and ensures they are walkable. | |
| 469 class ExclusiveLargePageIterator : ValueObject { | |
| 470 public: | |
| 471 explicit ExclusiveLargePageIterator(const PageSpace* space) | |
| 472 : space_(space), ml_(space->pages_lock_) { | |
| 473 space_->MakeIterable(); | |
| 474 page_ = space_->large_pages_; | |
| 475 } | |
| 476 HeapPage* page() const { return page_; } | |
| 477 bool Done() const { return page_ == NULL; } | |
| 478 void Advance() { | |
| 479 ASSERT(!Done()); | |
| 480 page_ = page_->next(); | |
| 481 } | |
| 482 private: | |
| 483 const PageSpace* space_; | |
| 484 MutexLocker ml_; | |
| 485 NoGCScope no_gc; | |
| 486 HeapPage* page_; | |
| 487 }; | |
| 488 | |
| 489 | |
| 446 void PageSpace::MakeIterable() const { | 490 void PageSpace::MakeIterable() const { |
| 447 // TODO(koda): Assert not called from concurrent sweeper task. | 491 // TODO(koda): Assert not called from concurrent sweeper task. |
| 448 if (bump_top_ < bump_end_) { | 492 if (bump_top_ < bump_end_) { |
| 449 FreeListElement::AsElement(bump_top_, bump_end_ - bump_top_); | 493 FreeListElement::AsElement(bump_top_, bump_end_ - bump_top_); |
| 450 } | 494 } |
| 451 } | 495 } |
| 452 | 496 |
| 453 | 497 |
| 454 bool PageSpace::Contains(uword addr) const { | 498 bool PageSpace::Contains(uword addr) const { |
| 455 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 499 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
| 456 if (it.page()->Contains(addr)) { | 500 if (it.page()->Contains(addr)) { |
| 457 return true; | 501 return true; |
| 458 } | 502 } |
| 459 } | 503 } |
| 460 return false; | 504 return false; |
| 461 } | 505 } |
| 462 | 506 |
| 463 | 507 |
| 464 bool PageSpace::Contains(uword addr, HeapPage::PageType type) const { | 508 bool PageSpace::Contains(uword addr, HeapPage::PageType type) const { |
| 509 if (type == HeapPage::kExecutable) { | |
| 510 // Fast path executable pages. | |
| 511 for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) { | |
| 512 if (it.page()->Contains(addr)) { | |
| 513 return true; | |
| 514 } | |
| 515 } | |
| 516 // Large pages can be executable, walk them too. | |
| 517 for (ExclusiveLargePageIterator it(this); !it.Done(); it.Advance()) { | |
| 518 if ((it.page()->type() == type) && it.page()->Contains(addr)) { | |
| 519 return true; | |
| 520 } | |
| 521 } | |
| 522 return false; | |
| 523 } | |
| 465 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 524 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
| 466 if ((it.page()->type() == type) && it.page()->Contains(addr)) { | 525 if ((it.page()->type() == type) && it.page()->Contains(addr)) { |
| 467 return true; | 526 return true; |
| 468 } | 527 } |
| 469 } | 528 } |
| 470 return false; | 529 return false; |
| 471 } | 530 } |
| 472 | 531 |
| 473 | 532 |
| 474 void PageSpace::StartEndAddress(uword* start, uword* end) const { | 533 void PageSpace::StartEndAddress(uword* start, uword* end) const { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 493 | 552 |
| 494 void PageSpace::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 553 void PageSpace::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| 495 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 554 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
| 496 it.page()->VisitObjectPointers(visitor); | 555 it.page()->VisitObjectPointers(visitor); |
| 497 } | 556 } |
| 498 } | 557 } |
| 499 | 558 |
| 500 | 559 |
| 501 RawObject* PageSpace::FindObject(FindObjectVisitor* visitor, | 560 RawObject* PageSpace::FindObject(FindObjectVisitor* visitor, |
| 502 HeapPage::PageType type) const { | 561 HeapPage::PageType type) const { |
| 562 if (type == HeapPage::kExecutable) { | |
| 563 // Fast path executable pages. | |
| 564 for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) { | |
| 565 RawObject* obj = it.page()->FindObject(visitor); | |
| 566 if (obj != Object::null()) { | |
| 567 return obj; | |
| 568 } | |
| 569 } | |
| 570 // Large pages can be executable, walk them too. | |
| 571 for (ExclusiveLargePageIterator it(this); !it.Done(); it.Advance()) { | |
| 572 if (it.page()->type() == type) { | |
| 573 RawObject* obj = it.page()->FindObject(visitor); | |
| 574 if (obj != Object::null()) { | |
| 575 return obj; | |
| 576 } | |
| 577 } | |
| 578 } | |
| 579 return Object::null(); | |
| 580 } | |
| 581 | |
| 503 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { | 582 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) { |
| 504 if (it.page()->type() == type) { | 583 if (it.page()->type() == type) { |
| 505 RawObject* obj = it.page()->FindObject(visitor); | 584 RawObject* obj = it.page()->FindObject(visitor); |
| 506 if (obj != Object::null()) { | 585 if (obj != Object::null()) { |
| 507 return obj; | 586 return obj; |
| 508 } | 587 } |
| 509 } | 588 } |
| 510 } | 589 } |
| 511 return Object::null(); | 590 return Object::null(); |
| 512 } | 591 } |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1022 return 0; | 1101 return 0; |
| 1023 } else { | 1102 } else { |
| 1024 ASSERT(total_time >= gc_time); | 1103 ASSERT(total_time >= gc_time); |
| 1025 int result = static_cast<int>((static_cast<double>(gc_time) / | 1104 int result = static_cast<int>((static_cast<double>(gc_time) / |
| 1026 static_cast<double>(total_time)) * 100); | 1105 static_cast<double>(total_time)) * 100); |
| 1027 return result; | 1106 return result; |
| 1028 } | 1107 } |
| 1029 } | 1108 } |
| 1030 | 1109 |
| 1031 } // namespace dart | 1110 } // namespace dart |
| OLD | NEW |