Revision: 3406 Author: [email protected] Date: Thu Dec 3 02:16:37 2009 Log: 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 http://code.google.com/p/v8/source/detail?r=3406 Modified: /branches/bleeding_edge/src/api.cc /branches/bleeding_edge/src/global-handles.cc /branches/bleeding_edge/src/global-handles.h /branches/bleeding_edge/src/heap.cc /branches/bleeding_edge/src/heap.h ======================================= --- /branches/bleeding_edge/src/api.cc Fri Nov 27 06:10:48 2009 +++ /branches/bleeding_edge/src/api.cc Thu Dec 3 02:16:37 2009 @@ -125,7 +125,8 @@ // When V8 cannot allocated memory FatalProcessOutOfMemory is called. // 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(); FatalErrorCallback callback = GetFatalErrorHandler(); { @@ -135,6 +136,13 @@ // If the callback returns, we stop execution. UNREACHABLE(); } + + +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) { ======================================= --- /branches/bleeding_edge/src/global-handles.cc Tue Nov 17 05:50:07 2009 +++ /branches/bleeding_edge/src/global-handles.cc Thu Dec 3 02:16:37 2009 @@ -429,6 +429,26 @@ GlobalHandles::Node* GlobalHandles::first_free_ = 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 void GlobalHandles::PrintStats() { ======================================= --- /branches/bleeding_edge/src/global-handles.h Wed Nov 11 01:50:06 2009 +++ /branches/bleeding_edge/src/global-handles.h Thu Dec 3 02:16:37 2009 @@ -77,6 +77,8 @@ // Returns the current 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. // These handles are also included in NumberOfWeakHandles(). ======================================= --- /branches/bleeding_edge/src/heap.cc Wed Dec 2 04:58:10 2009 +++ /branches/bleeding_edge/src/heap.cc Thu Dec 3 02:16:37 2009 @@ -3271,6 +3271,24 @@ bool Heap::ConfigureHeapDefault() { return ConfigureHeap(FLAG_max_new_space_size / 2, FLAG_max_old_space_size); } + + +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() { ======================================= --- /branches/bleeding_edge/src/heap.h Wed Nov 25 01:05:30 2009 +++ /branches/bleeding_edge/src/heap.h Thu Dec 3 02:16:37 2009 @@ -189,6 +189,7 @@ // Forward declaration of the GCTracer class. class GCTracer; +class HeapStats; // The all static Heap captures the interface to the global object heap. @@ -865,6 +866,8 @@ static RootListIndex RootIndexForExternalArrayType( ExternalArrayType array_type); + static void RecordStats(HeapStats* stats); + private: static int reserved_semispace_size_; static int max_semispace_size_; @@ -1100,6 +1103,28 @@ }; +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 { public: AlwaysAllocateScope() { -- v8-dev mailing list [email protected] http://groups.google.com/group/v8-dev
