926d554112
Review URL: https://chromiumcodereview.appspot.com//10093010 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@6578 260f80e4-7a28-3924-810f-c04153c831b5
161 lines
4.2 KiB
C++
161 lines
4.2 KiB
C++
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef VM_PAGES_H_
|
|
#define VM_PAGES_H_
|
|
|
|
#include "vm/freelist.h"
|
|
#include "vm/globals.h"
|
|
#include "vm/virtual_memory.h"
|
|
|
|
namespace dart {
|
|
|
|
// Forward declarations.
|
|
class Heap;
|
|
class ObjectPointerVisitor;
|
|
|
|
// An aligned page containing old generation objects. Alignment is used to be
|
|
// able to get to a HeapPage header quickly based on a pointer to an object.
|
|
class HeapPage {
|
|
public:
|
|
HeapPage* next() const { return next_; }
|
|
void set_next(HeapPage* next) { next_ = next; }
|
|
|
|
bool Contains(uword addr) {
|
|
return memory_->Contains(addr);
|
|
}
|
|
|
|
uword start() const { return reinterpret_cast<uword>(this); }
|
|
uword end() const { return memory_->end(); }
|
|
|
|
uword top() const { return top_; }
|
|
void set_top(uword top) { top_ = top; }
|
|
|
|
uword first_object_start() const {
|
|
return (reinterpret_cast<uword>(this) + sizeof(HeapPage));
|
|
}
|
|
|
|
void set_used(uword used) { used_ = used; }
|
|
uword used() const { return used_; }
|
|
void AddUsed(uword size) {
|
|
used_ += size;
|
|
}
|
|
|
|
uword TryBumpAllocate(intptr_t size) {
|
|
uword result = top();
|
|
intptr_t remaining_space = end() - result;
|
|
if (remaining_space < size) {
|
|
return 0;
|
|
}
|
|
set_top(result + size);
|
|
return result;
|
|
}
|
|
|
|
void VisitObjectPointers(ObjectPointerVisitor* visitor) const;
|
|
|
|
RawObject* FindObject(FindObjectVisitor* visitor) const;
|
|
|
|
private:
|
|
static HeapPage* Initialize(VirtualMemory* memory, bool is_executable);
|
|
static HeapPage* Allocate(intptr_t size, bool is_executable);
|
|
|
|
// Deallocate the virtual memory backing this page. The page pointer to this
|
|
// page becomes immediately inaccessible.
|
|
void Deallocate();
|
|
|
|
VirtualMemory* memory_;
|
|
HeapPage* next_;
|
|
uword used_;
|
|
uword top_;
|
|
|
|
friend class PageSpace;
|
|
|
|
DISALLOW_ALLOCATION();
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(HeapPage);
|
|
};
|
|
|
|
|
|
class PageSpace {
|
|
public:
|
|
// TODO(iposva): Determine heap sizes and tune the page size accordingly.
|
|
static const intptr_t kPageSize = 256 * KB;
|
|
static const intptr_t kPageAlignment = kPageSize;
|
|
|
|
PageSpace(Heap* heap, intptr_t max_capacity, bool is_executable = false);
|
|
~PageSpace();
|
|
|
|
uword TryAllocate(intptr_t size);
|
|
|
|
intptr_t in_use() const { return in_use_; }
|
|
bool Contains(uword addr) const;
|
|
bool IsValidAddress(uword addr) const {
|
|
return Contains(addr);
|
|
}
|
|
static bool IsPageAllocatableSize(intptr_t size) {
|
|
return size <= kAllocatablePageSize;
|
|
}
|
|
|
|
void VisitObjectPointers(ObjectPointerVisitor* visitor) const;
|
|
|
|
RawObject* FindObject(FindObjectVisitor* visitor) const;
|
|
|
|
// Collect the garbage in the page space using mark-sweep.
|
|
void MarkSweep(bool invoke_api_callbacks);
|
|
|
|
static HeapPage* PageFor(RawObject* raw_obj) {
|
|
return reinterpret_cast<HeapPage*>(
|
|
RawObject::ToAddr(raw_obj) & ~(kPageSize -1));
|
|
}
|
|
|
|
private:
|
|
static const intptr_t kAllocatablePageSize = kPageSize - sizeof(HeapPage);
|
|
|
|
void AllocatePage();
|
|
void FreePage(HeapPage* page, HeapPage* previous_page);
|
|
HeapPage* AllocateLargePage(intptr_t size);
|
|
void FreeLargePage(HeapPage* page, HeapPage* previous_page);
|
|
void FreePages(HeapPage* pages);
|
|
|
|
static intptr_t LargePageSizeFor(intptr_t size);
|
|
bool CanIncreaseCapacity(intptr_t increase) {
|
|
ASSERT(capacity_ <= max_capacity_);
|
|
return increase <= (max_capacity_ - capacity_);
|
|
}
|
|
|
|
uword TryBumpAllocate(intptr_t size);
|
|
|
|
FreeList freelist_;
|
|
|
|
Heap* heap_;
|
|
|
|
HeapPage* pages_;
|
|
HeapPage* large_pages_;
|
|
|
|
// Page being used for bump allocation.
|
|
// The value has different meanings:
|
|
// NULL: Still bump allocating from last allocated fresh page.
|
|
// !NULL: Last page that had enough room to bump allocate, when we reach the
|
|
// tail page, we give up bump allocating.
|
|
HeapPage* bump_page_;
|
|
|
|
// Various sizes being tracked for this generation.
|
|
intptr_t max_capacity_;
|
|
intptr_t capacity_;
|
|
intptr_t in_use_;
|
|
|
|
// Old-gen GC cycle count.
|
|
int count_;
|
|
|
|
bool is_executable_;
|
|
|
|
// Keep track whether a MarkSweep is currently running.
|
|
bool sweeping_;
|
|
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(PageSpace);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // VM_PAGES_H_
|