Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Unified Diff: src/spaces.h

Issue 7124006: Two-page newspace. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: Address review comments. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.cc ('k') | src/spaces.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/spaces.h
diff --git a/src/spaces.h b/src/spaces.h
index ae5a2d5a7ea11f6bbadccb687fa7d5c91d87178e..6c257398b9d5c28f109be6588b33677f6d0724d0 100644
--- a/src/spaces.h
+++ b/src/spaces.h
@@ -371,6 +371,13 @@ class MemoryChunk {
return addr >= body() && addr < address() + size();
}
+ // Checks whether addr can be a limit of addresses in this page.
+ // It's a limit if it's in the page, or if it's just after the
+ // last byte of the page.
+ bool ContainsLimit(Address addr) {
+ return addr >= body() && addr <= address() + size();
+ }
+
enum MemoryChunkFlags {
IS_EXECUTABLE,
WAS_SWEPT_CONSERVATIVELY,
@@ -1329,7 +1336,7 @@ class PagedSpace : public Space {
bool EnsureCapacity(int capacity);
// The dummy page that anchors the linked list of pages.
- Page *anchor() { return &anchor_; }
+ Page* anchor() { return &anchor_; }
#ifdef ENABLE_HEAP_PROTECTION
// Protect/unprotect the space by marking it read-only/writable.
@@ -1509,17 +1516,29 @@ class NewSpacePage : public MemoryChunk {
return reinterpret_cast<SemiSpace*>(owner());
}
- private:
- NewSpacePage(SemiSpace* owner) {
- InitializeAsAnchor(owner);
- }
+ bool is_anchor() { return !this->InNewSpace(); }
// Finds the NewSpacePage containg the given address.
- static NewSpacePage* FromAddress(Address address_in_page) {
+ static inline NewSpacePage* FromAddress(Address address_in_page) {
Address page_start =
reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(address_in_page) &
~Page::kPageAlignmentMask);
- return reinterpret_cast<NewSpacePage*>(page_start);
+ NewSpacePage* page = reinterpret_cast<NewSpacePage*>(page_start);
+ ASSERT(page->InNewSpace());
+ return page;
+ }
+
+ // Find the page for a limit address. A limit address is either an address
+ // inside a page, or the address right after the last byte of a page.
+ static inline NewSpacePage* FromLimit(Address address_limit) {
+ return NewSpacePage::FromAddress(address_limit - 1);
+ }
+
+ private:
+ // Create a NewSpacePage object that is only used as anchor
+ // for the doubly-linked list of real pages.
+ explicit NewSpacePage(SemiSpace* owner) {
+ InitializeAsAnchor(owner);
}
static NewSpacePage* Initialize(Heap* heap,
@@ -1528,7 +1547,7 @@ class NewSpacePage : public MemoryChunk {
// Intialize a fake NewSpacePage used as sentinel at the ends
// of a doubly-linked list of real NewSpacePages.
- // Only uses the prev/next links.
+ // Only uses the prev/next links, and sets flags to not be in new-space.
void InitializeAsAnchor(SemiSpace* owner);
friend class SemiSpace;
@@ -1580,7 +1599,7 @@ class SemiSpace : public Space {
bool ShrinkTo(int new_capacity);
// Returns the start address of the first page of the space.
- Address low() {
+ Address space_low() {
ASSERT(anchor_.next_page() != &anchor_);
return anchor_.next_page()->body();
}
@@ -1592,11 +1611,22 @@ class SemiSpace : public Space {
}
// Returns one past the end address of the space.
- Address high() {
- // TODO(gc): Change when there is more than one page.
+ Address space_high() {
+ return anchor_.prev_page()->body_limit();
+ }
+
+ // Returns one past the end address of the current page of the space.
+ Address page_high() {
return current_page_->body_limit();
}
+ bool AdvancePage() {
+ NewSpacePage* next_page = current_page_->next_page();
+ if (next_page == &anchor_) return false;
+ current_page_ = next_page;
+ return true;
+ }
+
// Resets the space to using the first page.
void Reset();
@@ -1604,11 +1634,6 @@ class SemiSpace : public Space {
Address age_mark() { return age_mark_; }
void set_age_mark(Address mark) { age_mark_ = mark; }
- // The offset of an address from the beginning of the space.
- int SpaceOffsetForAddress(Address addr) {
- return static_cast<int>(addr - low());
- }
-
// If we don't have these here then SemiSpace will be abstract. However
// they should never be called.
virtual intptr_t Size() {
@@ -1625,7 +1650,7 @@ class SemiSpace : public Space {
bool Commit();
bool Uncommit();
- NewSpacePage* first_page() { return NewSpacePage::FromAddress(start_); }
+ NewSpacePage* first_page() { return anchor_.next_page(); }
NewSpacePage* current_page() { return current_page_; }
#ifdef ENABLE_HEAP_PROTECTION
@@ -1637,6 +1662,7 @@ class SemiSpace : public Space {
#ifdef DEBUG
virtual void Print();
virtual void Verify();
+ static void ValidateRange(Address from, Address to);
#endif
// Returns the current capacity of the semi space.
@@ -1657,6 +1683,8 @@ class SemiSpace : public Space {
// Copies the flags into the masked positions on all pages in the space.
void FlipPages(intptr_t flags, intptr_t flag_mask);
+ NewSpacePage* anchor() { return &anchor_; }
+
// The current and maximum capacity of the space.
int capacity_;
int maximum_capacity_;
@@ -1678,6 +1706,8 @@ class SemiSpace : public Space {
NewSpacePage anchor_;
NewSpacePage* current_page_;
+ friend class SemiSpaceIterator;
+ friend class NewSpacePageIterator;
public:
TRACK_MEMORY("SemiSpace")
};
@@ -1693,15 +1723,26 @@ class SemiSpaceIterator : public ObjectIterator {
// Create an iterator over the objects in the given space. If no start
// address is given, the iterator starts from the bottom of the space. If
// no size function is given, the iterator calls Object::Size().
+
+ // Iterate over all of allocated to-space.
explicit SemiSpaceIterator(NewSpace* space);
+ // Iterate over all of allocated to-space, with a custome size function.
SemiSpaceIterator(NewSpace* space, HeapObjectCallback size_func);
+ // Iterate over part of allocated to-space, from start to the end
+ // of allocation.
SemiSpaceIterator(NewSpace* space, Address start);
+ // Iterate from one address to another in the same semi-space.
+ SemiSpaceIterator(Address from, Address to);
HeapObject* Next() {
+ if (current_ == limit_) return NULL;
if (current_ == current_page_limit_) {
- // TODO(gc): Add something here when we have more than one page.
+ NewSpacePage* page = NewSpacePage::FromAddress(current_ - 1);
+ page = page->next_page();
+ ASSERT(!page->is_anchor());
+ current_ = page->body();
+ if (current_ == limit_) return NULL;
}
- if (current_ == limit_) return NULL;
HeapObject* object = HeapObject::FromAddress(current_);
int size = (size_func_ == NULL) ? object->Size() : size_func_(object);
@@ -1714,13 +1755,10 @@ class SemiSpaceIterator : public ObjectIterator {
virtual HeapObject* next_object() { return Next(); }
private:
- void Initialize(NewSpace* space,
- Address start,
+ void Initialize(Address start,
Address end,
HeapObjectCallback size_func);
- // The semispace.
- SemiSpace* space_;
// The current iteration point.
Address current_;
// The end of the current page.
@@ -1733,6 +1771,30 @@ class SemiSpaceIterator : public ObjectIterator {
// -----------------------------------------------------------------------------
+// A PageIterator iterates the pages in a semi-space.
+class NewSpacePageIterator BASE_EMBEDDED {
+ public:
+ // Make an iterator that runs over all pages in the given semispace,
+ // even those not used in allocation.
+ explicit inline NewSpacePageIterator(SemiSpace* space);
+ // Make iterator that iterates from the page containing start
+ // to the page that contains limit in the same semispace.
+ inline NewSpacePageIterator(Address start, Address limit);
+
+ inline bool has_next();
+ inline NewSpacePage* next();
+
+ private:
+ NewSpacePage* prev_page_; // Previous page returned.
+ // Next page that will be returned. Cached here so that we can use this
+ // iterator for operations that deallocate pages.
+ NewSpacePage* next_page_;
+ // Last page returned.
+ NewSpacePage* last_page_;
+};
+
+
+// -----------------------------------------------------------------------------
// The young generation space.
//
// The new space consists of a contiguous pair of semispaces. It simply
@@ -1818,8 +1880,11 @@ class NewSpace : public Space {
return Capacity();
}
- // Return the available bytes without growing in the active semispace.
- intptr_t Available() { return Capacity() - Size(); }
+ // Return the available bytes without growing or switching page in the
+ // active semispace.
+ intptr_t Available() {
+ return allocation_info_.limit - allocation_info_.top;
+ }
// Return the maximum capacity of a semispace.
int MaximumCapacity() {
@@ -1836,7 +1901,7 @@ class NewSpace : public Space {
// Return the address of the allocation pointer in the active semispace.
Address top() { return allocation_info_.top; }
// Return the address of the first object in the active semispace.
- Address bottom() { return to_space_.low(); }
+ Address bottom() { return to_space_.space_low(); }
// Get the age mark of the inactive semispace.
Address age_mark() { return from_space_.age_mark(); }
@@ -1873,7 +1938,7 @@ class NewSpace : public Space {
void LowerInlineAllocationLimit(intptr_t step) {
inline_alloction_limit_step_ = step;
if (step == 0) {
- allocation_info_.limit = to_space_.high();
+ allocation_info_.limit = to_space_.page_high();
} else {
allocation_info_.limit = Min(
allocation_info_.top + inline_alloction_limit_step_,
@@ -1882,22 +1947,15 @@ class NewSpace : public Space {
top_on_previous_step_ = allocation_info_.top;
}
- // Get the extent of the inactive semispace (for use as a marking stack).
- Address FromSpaceLow() { return from_space_.low(); }
- Address FromSpaceHigh() { return from_space_.high(); }
+ // Get the extent of the inactive semispace (for use as a marking stack,
+ // or to zap it).
+ Address FromSpacePageLow() { return from_space_.page_low(); }
+ Address FromSpaceLow() { return from_space_.space_low(); }
+ Address FromSpaceHigh() { return from_space_.space_high(); }
- // Get the extent of the active semispace (to sweep newly copied objects
- // during a scavenge collection).
- Address ToSpaceLow() { return to_space_.low(); }
- Address ToSpaceHigh() { return to_space_.high(); }
-
- // Offsets from the beginning of the semispaces.
- int ToSpaceOffsetForAddress(Address a) {
- return to_space_.SpaceOffsetForAddress(a);
- }
- int FromSpaceOffsetForAddress(Address a) {
- return from_space_.SpaceOffsetForAddress(a);
- }
+ // Get the extent of the active semispace's pages' memory.
+ Address ToSpaceLow() { return to_space_.space_low(); }
+ Address ToSpaceHigh() { return to_space_.space_high(); }
inline bool ToSpaceContains(Address address) {
MemoryChunk* page = MemoryChunk::FromAddress(address);
@@ -1924,6 +1982,12 @@ class NewSpace : public Space {
return FromSpaceContains(address);
}
+ // Try to switch the active semispace to a new, empty, page.
+ // Returns false if this isn't possible or reasonable (i.e., there
+ // are no pages, or the current page is already empty), or true
+ // if successful.
+ bool AddFreshPage();
+
virtual bool ReserveSpace(int bytes);
// Resizes a sequential string which must be the most recent thing that was
@@ -1983,6 +2047,9 @@ class NewSpace : public Space {
}
private:
+ // Update allocation info to match the current to-space page.
+ void UpdateAllocationInfo();
+
Address chunk_base_;
uintptr_t chunk_size_;
@@ -2055,9 +2122,9 @@ class OldSpace : public PagedSpace {
// For contiguous spaces, top should be in the space (or at the end) and limit
// should be the end of the space.
#define ASSERT_SEMISPACE_ALLOCATION_INFO(info, space) \
- ASSERT((space).low() <= (info).top \
- && (info).top <= (space).high() \
- && (info).limit <= (space).high())
+ ASSERT((space).page_low() <= (info).top \
+ && (info).top <= (space).page_high() \
+ && (info).limit <= (space).page_high())
// -----------------------------------------------------------------------------
« no previous file with comments | « src/runtime.cc ('k') | src/spaces.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698