Added recording of heap and global handle stats in a stack-allocated

struct on fatal out of memory.  This should cause the information to
be included in minidumps so we can get a better idea of the state of
v8 on OOMs.

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


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3406 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2cfb4941
...@@ -125,7 +125,8 @@ static FatalErrorCallback& GetFatalErrorHandler() { ...@@ -125,7 +125,8 @@ static FatalErrorCallback& GetFatalErrorHandler() {
// When V8 cannot allocated memory FatalProcessOutOfMemory is called. // When V8 cannot allocated memory FatalProcessOutOfMemory is called.
// The default fatal error handler is called and execution is stopped. // The default fatal error handler is called and execution is stopped.
void i::V8::FatalProcessOutOfMemory(const char* location) { static void ExecuteFatalProcessOutOfMemory(const char* location,
i::HeapStats* heap_stats) {
i::V8::SetFatalError(); i::V8::SetFatalError();
FatalErrorCallback callback = GetFatalErrorHandler(); FatalErrorCallback callback = GetFatalErrorHandler();
{ {
...@@ -137,6 +138,13 @@ void i::V8::FatalProcessOutOfMemory(const char* location) { ...@@ -137,6 +138,13 @@ void i::V8::FatalProcessOutOfMemory(const char* location) {
} }
void i::V8::FatalProcessOutOfMemory(const char* location) {
i::HeapStats heap_stats;
i::Heap::RecordStats(&heap_stats);
ExecuteFatalProcessOutOfMemory(location, &heap_stats);
}
void V8::SetFatalErrorHandler(FatalErrorCallback that) { void V8::SetFatalErrorHandler(FatalErrorCallback that) {
exception_behavior = that; exception_behavior = that;
} }
......
...@@ -429,6 +429,26 @@ GlobalHandles::Node* GlobalHandles::head_ = NULL; ...@@ -429,6 +429,26 @@ GlobalHandles::Node* GlobalHandles::head_ = NULL;
GlobalHandles::Node* GlobalHandles::first_free_ = NULL; GlobalHandles::Node* GlobalHandles::first_free_ = NULL;
GlobalHandles::Node* GlobalHandles::first_deallocated_ = NULL; GlobalHandles::Node* GlobalHandles::first_deallocated_ = NULL;
void GlobalHandles::RecordStats(HeapStats* stats) {
stats->global_handle_count = 0;
stats->weak_global_handle_count = 0;
stats->pending_global_handle_count = 0;
stats->near_death_global_handle_count = 0;
stats->destroyed_global_handle_count = 0;
for (Node* current = head_; current != NULL; current = current->next()) {
stats->global_handle_count++;
if (current->state_ == Node::WEAK) {
stats->weak_global_handle_count++;
} else if (current->state_ == Node::PENDING) {
stats->pending_global_handle_count++;
} else if (current->state_ == Node::NEAR_DEATH) {
stats->near_death_global_handle_count++;
} else if (current->state_ == Node::DESTROYED) {
stats->destroyed_global_handle_count++;
}
}
}
#ifdef DEBUG #ifdef DEBUG
void GlobalHandles::PrintStats() { void GlobalHandles::PrintStats() {
......
...@@ -78,6 +78,8 @@ class GlobalHandles : public AllStatic { ...@@ -78,6 +78,8 @@ class GlobalHandles : public AllStatic {
// Returns the current number of weak handles. // Returns the current number of weak handles.
static int NumberOfWeakHandles() { return number_of_weak_handles_; } static int NumberOfWeakHandles() { return number_of_weak_handles_; }
static void RecordStats(HeapStats* stats);
// Returns the current number of weak handles to global objects. // Returns the current number of weak handles to global objects.
// These handles are also included in NumberOfWeakHandles(). // These handles are also included in NumberOfWeakHandles().
static int NumberOfGlobalObjectWeakHandles() { static int NumberOfGlobalObjectWeakHandles() {
......
...@@ -3273,6 +3273,24 @@ bool Heap::ConfigureHeapDefault() { ...@@ -3273,6 +3273,24 @@ bool Heap::ConfigureHeapDefault() {
} }
void Heap::RecordStats(HeapStats* stats) {
stats->new_space_size = new_space_.Size();
stats->new_space_capacity = new_space_.Capacity();
stats->old_pointer_space_size = old_pointer_space_->Size();
stats->old_pointer_space_capacity = old_pointer_space_->Capacity();
stats->old_data_space_size = old_data_space_->Size();
stats->old_data_space_capacity = old_data_space_->Capacity();
stats->code_space_size = code_space_->Size();
stats->code_space_capacity = code_space_->Capacity();
stats->map_space_size = map_space_->Size();
stats->map_space_capacity = map_space_->Capacity();
stats->cell_space_size = cell_space_->Size();
stats->cell_space_capacity = cell_space_->Capacity();
stats->lo_space_size = lo_space_->Size();
GlobalHandles::RecordStats(stats);
}
int Heap::PromotedSpaceSize() { int Heap::PromotedSpaceSize() {
return old_pointer_space_->Size() return old_pointer_space_->Size()
+ old_data_space_->Size() + old_data_space_->Size()
......
...@@ -189,6 +189,7 @@ namespace internal { ...@@ -189,6 +189,7 @@ namespace internal {
// Forward declaration of the GCTracer class. // Forward declaration of the GCTracer class.
class GCTracer; class GCTracer;
class HeapStats;
// The all static Heap captures the interface to the global object heap. // The all static Heap captures the interface to the global object heap.
...@@ -865,6 +866,8 @@ class Heap : public AllStatic { ...@@ -865,6 +866,8 @@ class Heap : public AllStatic {
static RootListIndex RootIndexForExternalArrayType( static RootListIndex RootIndexForExternalArrayType(
ExternalArrayType array_type); ExternalArrayType array_type);
static void RecordStats(HeapStats* stats);
private: private:
static int reserved_semispace_size_; static int reserved_semispace_size_;
static int max_semispace_size_; static int max_semispace_size_;
...@@ -1100,6 +1103,28 @@ class Heap : public AllStatic { ...@@ -1100,6 +1103,28 @@ class Heap : public AllStatic {
}; };
struct HeapStats {
int new_space_size;
int new_space_capacity;
int old_pointer_space_size;
int old_pointer_space_capacity;
int old_data_space_size;
int old_data_space_capacity;
int code_space_size;
int code_space_capacity;
int map_space_size;
int map_space_capacity;
int cell_space_size;
int cell_space_capacity;
int lo_space_size;
int global_handle_count;
int weak_global_handle_count;
int pending_global_handle_count;
int near_death_global_handle_count;
int destroyed_global_handle_count;
};
class AlwaysAllocateScope { class AlwaysAllocateScope {
public: public:
AlwaysAllocateScope() { AlwaysAllocateScope() {
......
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