Added recording of heap and global handle stats in a stack-allocated
authorchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Dec 2009 10:16:37 +0000 (10:16 +0000)
committerchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 3 Dec 2009 10:16:37 +0000 (10:16 +0000)
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

src/api.cc
src/global-handles.cc
src/global-handles.h
src/heap.cc
src/heap.h

index 3a2f8ab745ba225fbd4411a08070c76060ad006c..eaff86255f2d15403bd7b738d4a2fbc95e379fa3 100644 (file)
@@ -125,7 +125,8 @@ static FatalErrorCallback& GetFatalErrorHandler() {
 
 // 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();
   {
@@ -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) {
   exception_behavior = that;
 }
index e519d7077fa5e4fa34517410f427bf73a62a31a9..5b01f61f3af5a1fba7fd1a8064eca55b5a7f2ea1 100644 (file)
@@ -429,6 +429,26 @@ GlobalHandles::Node* GlobalHandles::head_ = NULL;
 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() {
index b9cac5c2a16e112e19057ffecc0436742de527b3..659f86eca70251687a009c585e4d59936e731edd 100644 (file)
@@ -78,6 +78,8 @@ class GlobalHandles : public AllStatic {
   // 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().
   static int NumberOfGlobalObjectWeakHandles() {
index 79a91cfc00407fe84b0650c916f7a0f9751316a2..39f00d3b437874a528176f1f4cfcbc8db87b6367 100644 (file)
@@ -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() {
   return old_pointer_space_->Size()
       + old_data_space_->Size()
index 80cc885a80c95857498ced94d1ceeba38b20d5cf..8bc55e80315e172de9d65db28e2751d744c883ef 100644 (file)
@@ -189,6 +189,7 @@ namespace internal {
 
 // 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 @@ class Heap : public AllStatic {
   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 @@ 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 {
  public:
   AlwaysAllocateScope() {