Add information about memory allocator's size and capacity and heap snapshot into...
authorantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 5 Aug 2010 14:12:50 +0000 (14:12 +0000)
committerantonm@chromium.org <antonm@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 5 Aug 2010 14:12:50 +0000 (14:12 +0000)
That might help us debug OOM crashes in V8.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5181 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/api.cc
src/heap-inl.h
src/heap.cc
src/heap.h
src/v8.h

index 48c64b3..4fdc95f 100644 (file)
@@ -126,7 +126,7 @@ 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) {
+void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
   i::HeapStats heap_stats;
   int start_marker;
   heap_stats.start_marker = &start_marker;
@@ -166,9 +166,17 @@ void i::V8::FatalProcessOutOfMemory(const char* location) {
   heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
   int destroyed_global_handle_count;
   heap_stats.destroyed_global_handle_count = &destroyed_global_handle_count;
+  int memory_allocator_size;
+  heap_stats.memory_allocator_size = &memory_allocator_size;
+  int memory_allocator_capacity;
+  heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
+  int objects_per_type[LAST_TYPE + 1] = {0};
+  heap_stats.objects_per_type = objects_per_type;
+  int size_per_type[LAST_TYPE + 1] = {0};
+  heap_stats.size_per_type = size_per_type;
   int end_marker;
   heap_stats.end_marker = &end_marker;
-  i::Heap::RecordStats(&heap_stats);
+  i::Heap::RecordStats(&heap_stats, take_snapshot);
   i::V8::SetFatalError();
   FatalErrorCallback callback = GetFatalErrorHandler();
   {
index 5cb24ee..656c554 100644 (file)
@@ -390,7 +390,7 @@ void Heap::SetLastScriptId(Object* last_script_id) {
     Object* __object__ = FUNCTION_CALL;                                   \
     if (!__object__->IsFailure()) RETURN_VALUE;                           \
     if (__object__->IsOutOfMemoryFailure()) {                             \
-      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0");      \
+      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_0", true);\
     }                                                                     \
     if (!__object__->IsRetryAfterGC()) RETURN_EMPTY;                      \
     Heap::CollectGarbage(Failure::cast(__object__)->requested(),          \
@@ -398,7 +398,7 @@ void Heap::SetLastScriptId(Object* last_script_id) {
     __object__ = FUNCTION_CALL;                                           \
     if (!__object__->IsFailure()) RETURN_VALUE;                           \
     if (__object__->IsOutOfMemoryFailure()) {                             \
-      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1");      \
+      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_1", true);\
     }                                                                     \
     if (!__object__->IsRetryAfterGC()) RETURN_EMPTY;                      \
     Counters::gc_last_resort_from_handles.Increment();                    \
@@ -411,7 +411,7 @@ void Heap::SetLastScriptId(Object* last_script_id) {
     if (__object__->IsOutOfMemoryFailure() ||                             \
         __object__->IsRetryAfterGC()) {                                   \
       /* TODO(1181417): Fix this. */                                      \
-      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2");      \
+      v8::internal::V8::FatalProcessOutOfMemory("CALL_AND_RETRY_2", true);\
     }                                                                     \
     RETURN_EMPTY;                                                         \
   } while (false)
index 9f27a49..c4d0439 100644 (file)
@@ -4106,7 +4106,7 @@ bool Heap::ConfigureHeapDefault() {
 }
 
 
-void Heap::RecordStats(HeapStats* stats) {
+void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
   *stats->start_marker = 0xDECADE00;
   *stats->end_marker = 0xDECADE01;
   *stats->new_space_size = new_space_.Size();
@@ -4123,6 +4123,23 @@ void Heap::RecordStats(HeapStats* stats) {
   *stats->cell_space_capacity = cell_space_->Capacity();
   *stats->lo_space_size = lo_space_->Size();
   GlobalHandles::RecordStats(stats);
+  *stats->memory_allocator_size = MemoryAllocator::Size();
+  *stats->memory_allocator_capacity =
+      MemoryAllocator::Size() + MemoryAllocator::Available();
+  if (take_snapshot) {
+    HeapIterator iterator;
+    for (HeapObject* obj = iterator.next();
+         obj != NULL;
+         obj = iterator.next()) {
+      // Note: snapshot won't be precise because IsFreeListNode returns true
+      // for any bytearray.
+      if (FreeListNode::IsFreeListNode(obj)) continue;
+      InstanceType type = obj->map()->instance_type();
+      ASSERT(0 <= type && type <= LAST_TYPE);
+      stats->objects_per_type[type]++;
+      stats->size_per_type[type] += obj->Size();
+    }
+  }
 }
 
 
index f37aa80..a0b2157 100644 (file)
@@ -981,7 +981,7 @@ class Heap : public AllStatic {
   static RootListIndex RootIndexForExternalArrayType(
       ExternalArrayType array_type);
 
-  static void RecordStats(HeapStats* stats);
+  static void RecordStats(HeapStats* stats, bool take_snapshot = false);
 
   static Scavenger GetScavenger(int instance_type, int instance_size);
 
@@ -1324,26 +1324,30 @@ class Heap : public AllStatic {
 
 class HeapStats {
  public:
-  int* start_marker;
-  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;
-  int* end_marker;
+  int* start_marker;                    //  0
+  int* new_space_size;                  //  1
+  int* new_space_capacity;              //  2
+  int* old_pointer_space_size;          //  3
+  int* old_pointer_space_capacity;      //  4
+  int* old_data_space_size;             //  5
+  int* old_data_space_capacity;         //  6
+  int* code_space_size;                 //  7
+  int* code_space_capacity;             //  8
+  int* map_space_size;                  //  9
+  int* map_space_capacity;              // 10
+  int* cell_space_size;                 // 11
+  int* cell_space_capacity;             // 12
+  int* lo_space_size;                   // 13
+  int* global_handle_count;             // 14
+  int* weak_global_handle_count;        // 15
+  int* pending_global_handle_count;     // 16
+  int* near_death_global_handle_count;  // 17
+  int* destroyed_global_handle_count;   // 18
+  int* memory_allocator_size;           // 19
+  int* memory_allocator_capacity;       // 20
+  int* objects_per_type;                // 21
+  int* size_per_type;                   // 22
+  int* end_marker;                      // 23
 };
 
 
index 966d5a9..f761d38 100644 (file)
--- a/src/v8.h
+++ b/src/v8.h
@@ -92,7 +92,8 @@ class V8 : public AllStatic {
   static void SetFatalError();
 
   // Report process out of memory. Implementation found in api.cc.
-  static void FatalProcessOutOfMemory(const char* location);
+  static void FatalProcessOutOfMemory(const char* location,
+                                      bool take_snapshot = false);
 
   // Random number generation support. Not cryptographically safe.
   static uint32_t Random();