From: antonm@chromium.org Date: Thu, 5 Aug 2010 14:12:50 +0000 (+0000) Subject: Add information about memory allocator's size and capacity and heap snapshot into... X-Git-Tag: upstream/4.7.83~21409 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=791fa08ab71e716829ddaa500d46eba68addacda;p=platform%2Fupstream%2Fv8.git Add information about memory allocator's size and capacity and heap snapshot into heap stats. 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 --- diff --git a/src/api.cc b/src/api.cc index 48c64b3..4fdc95f 100644 --- a/src/api.cc +++ b/src/api.cc @@ -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(); { diff --git a/src/heap-inl.h b/src/heap-inl.h index 5cb24ee..656c554 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -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) diff --git a/src/heap.cc b/src/heap.cc index 9f27a49..c4d0439 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -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(); + } + } } diff --git a/src/heap.h b/src/heap.h index f37aa80..a0b2157 100644 --- a/src/heap.h +++ b/src/heap.h @@ -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 }; diff --git a/src/v8.h b/src/v8.h index 966d5a9..f761d38 100644 --- 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();