Commit 390fd2a3 authored by ager@chromium.org's avatar ager@chromium.org

Add an API to V8 to get simple heap statistics.

Review URL: http://codereview.chromium.org/261037

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3089 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 846688f8
...@@ -2102,6 +2102,29 @@ enum ProfilerModules { ...@@ -2102,6 +2102,29 @@ enum ProfilerModules {
}; };
/**
* Collection of V8 heap information.
*
* Instances of this class can be passed to v8::V8::HeapStatistics to
* get heap statistics from V8.
*/
class V8EXPORT HeapStatistics {
public:
HeapStatistics();
size_t total_heap_size() { return total_heap_size_; }
size_t used_heap_size() { return used_heap_size_; }
private:
void set_total_heap_size(size_t size) { total_heap_size_ = size; }
void set_used_heap_size(size_t size) { used_heap_size_ = size; }
size_t total_heap_size_;
size_t used_heap_size_;
friend class V8;
};
/** /**
* Container class for static utility functions. * Container class for static utility functions.
*/ */
...@@ -2352,6 +2375,10 @@ class V8EXPORT V8 { ...@@ -2352,6 +2375,10 @@ class V8EXPORT V8 {
*/ */
static bool Dispose(); static bool Dispose();
/**
* Get statistics about the heap memory usage.
*/
static void GetHeapStatistics(HeapStatistics* heap_statistics);
/** /**
* Optional notification that the embedder is idle. * Optional notification that the embedder is idle.
......
...@@ -2611,6 +2611,15 @@ bool v8::V8::Dispose() { ...@@ -2611,6 +2611,15 @@ bool v8::V8::Dispose() {
} }
HeapStatistics::HeapStatistics(): total_heap_size_(0), used_heap_size_(0) { }
void v8::V8::GetHeapStatistics(HeapStatistics* heap_statistics) {
heap_statistics->set_total_heap_size(i::Heap::CommittedMemory());
heap_statistics->set_used_heap_size(i::Heap::SizeOfObjects());
}
bool v8::V8::IdleNotification() { bool v8::V8::IdleNotification() {
// Returning true tells the caller that it need not // Returning true tells the caller that it need not
// continue to call IdleNotification. // continue to call IdleNotification.
......
...@@ -127,6 +127,19 @@ int Heap::Capacity() { ...@@ -127,6 +127,19 @@ int Heap::Capacity() {
} }
int Heap::CommittedMemory() {
if (!HasBeenSetup()) return 0;
return new_space_.CommittedMemory() +
old_pointer_space_->CommittedMemory() +
old_data_space_->CommittedMemory() +
code_space_->CommittedMemory() +
map_space_->CommittedMemory() +
cell_space_->CommittedMemory() +
lo_space_->Size();
}
int Heap::Available() { int Heap::Available() {
if (!HasBeenSetup()) return 0; if (!HasBeenSetup()) return 0;
...@@ -222,19 +235,34 @@ void Heap::ReportStatisticsBeforeGC() { ...@@ -222,19 +235,34 @@ void Heap::ReportStatisticsBeforeGC() {
void Heap::PrintShortHeapStatistics() { void Heap::PrintShortHeapStatistics() {
if (!FLAG_trace_gc_verbose) return; if (!FLAG_trace_gc_verbose) return;
PrintF("Memory allocator, used: %8d, available: %8d\n", PrintF("Memory allocator, used: %8d, available: %8d\n",
MemoryAllocator::Size(), MemoryAllocator::Available()); MemoryAllocator::Size(),
MemoryAllocator::Available());
PrintF("New space, used: %8d, available: %8d\n", PrintF("New space, used: %8d, available: %8d\n",
Heap::new_space_.Size(), new_space_.Available()); Heap::new_space_.Size(),
PrintF("Old pointers, used: %8d, available: %8d\n", new_space_.Available());
old_pointer_space_->Size(), old_pointer_space_->Available()); PrintF("Old pointers, used: %8d, available: %8d, waste: %8d\n",
PrintF("Old data space, used: %8d, available: %8d\n", old_pointer_space_->Size(),
old_data_space_->Size(), old_data_space_->Available()); old_pointer_space_->Available(),
PrintF("Code space, used: %8d, available: %8d\n", old_pointer_space_->Waste());
code_space_->Size(), code_space_->Available()); PrintF("Old data space, used: %8d, available: %8d, waste: %8d\n",
PrintF("Map space, used: %8d, available: %8d\n", old_data_space_->Size(),
map_space_->Size(), map_space_->Available()); old_data_space_->Available(),
old_data_space_->Waste());
PrintF("Code space, used: %8d, available: %8d, waste: %8d\n",
code_space_->Size(),
code_space_->Available(),
code_space_->Waste());
PrintF("Map space, used: %8d, available: %8d, waste: %8d\n",
map_space_->Size(),
map_space_->Available(),
map_space_->Waste());
PrintF("Cell space, used: %8d, available: %8d, waste: %8d\n",
cell_space_->Size(),
cell_space_->Available(),
cell_space_->Waste());
PrintF("Large object space, used: %8d, avaialble: %8d\n", PrintF("Large object space, used: %8d, avaialble: %8d\n",
lo_space_->Size(), lo_space_->Available()); lo_space_->Size(),
lo_space_->Available());
} }
#endif #endif
......
...@@ -260,6 +260,9 @@ class Heap : public AllStatic { ...@@ -260,6 +260,9 @@ class Heap : public AllStatic {
// more spaces are needed until it reaches the limit. // more spaces are needed until it reaches the limit.
static int Capacity(); static int Capacity();
// Returns the amount of memory currently committed for the heap.
static int CommittedMemory();
// Returns the available bytes in space w/o growing. // Returns the available bytes in space w/o growing.
// Heap doesn't guarantee that it can allocate an object that requires // Heap doesn't guarantee that it can allocate an object that requires
// all available bytes. Check MaxHeapObjectSize() instead. // all available bytes. Check MaxHeapObjectSize() instead.
......
...@@ -862,6 +862,10 @@ class PagedSpace : public Space { ...@@ -862,6 +862,10 @@ class PagedSpace : public Space {
// Current capacity without growing (Size() + Available() + Waste()). // Current capacity without growing (Size() + Available() + Waste()).
int Capacity() { return accounting_stats_.Capacity(); } int Capacity() { return accounting_stats_.Capacity(); }
// Total amount of memory committed for this space. For paged
// spaces this equals the capacity.
int CommittedMemory() { return Capacity(); }
// Available bytes without growing. // Available bytes without growing.
int Available() { return accounting_stats_.Available(); } int Available() { return accounting_stats_.Available(); }
...@@ -1252,11 +1256,19 @@ class NewSpace : public Space { ...@@ -1252,11 +1256,19 @@ class NewSpace : public Space {
// Return the allocated bytes in the active semispace. // Return the allocated bytes in the active semispace.
virtual int Size() { return top() - bottom(); } virtual int Size() { return top() - bottom(); }
// Return the current capacity of a semispace. // Return the current capacity of a semispace.
int Capacity() { int Capacity() {
ASSERT(to_space_.Capacity() == from_space_.Capacity()); ASSERT(to_space_.Capacity() == from_space_.Capacity());
return to_space_.Capacity(); return to_space_.Capacity();
} }
// Return the total amount of memory committed for new space.
int CommittedMemory() {
if (from_space_.is_committed()) return 2 * Capacity();
return Capacity();
}
// Return the available bytes without growing in the active semispace. // Return the available bytes without growing in the active semispace.
int Available() { return Capacity() - Size(); } int Available() { return Capacity() - Size(); }
......
...@@ -8153,3 +8153,15 @@ TEST(SetResourceConstraintsInThread) { ...@@ -8153,3 +8153,15 @@ TEST(SetResourceConstraintsInThread) {
CHECK(stack_limit == set_limit); CHECK(stack_limit == set_limit);
} }
} }
THREADED_TEST(GetHeapStatistics) {
v8::HandleScope scope;
LocalContext c1;
v8::HeapStatistics heap_statistics;
CHECK_EQ(heap_statistics.total_heap_size(), 0);
CHECK_EQ(heap_statistics.used_heap_size(), 0);
v8::V8::GetHeapStatistics(&heap_statistics);
CHECK_NE(heap_statistics.total_heap_size(), 0);
CHECK_NE(heap_statistics.used_heap_size(), 0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment