Commit 66083dd0 authored by ssid's avatar ssid Committed by Commit bot

Adding api to get last gc object statistics for chrome://tracing.

For dumping the number of objects and size of objects alive after the
last gc into chrome://tracing memory dumps, this CL adds new api to
get these number for each isolate.

Note: Chrome should be run with --js-flags='--track_gc_object_stats
--noincremental-marking' for object tracking.

BUG=476013
LOG=Y

Review URL: https://codereview.chromium.org/1113233002

Cr-Commit-Position: refs/heads/master@{#28474}
parent 24768fe2
......@@ -4839,6 +4839,24 @@ class V8_EXPORT HeapSpaceStatistics {
};
class V8_EXPORT HeapObjectStatistics {
public:
HeapObjectStatistics();
const char* object_type() { return object_type_; }
const char* object_sub_type() { return object_sub_type_; }
size_t object_count() { return object_count_; }
size_t object_size() { return object_size_; }
private:
const char* object_type_;
const char* object_sub_type_;
size_t object_count_;
size_t object_size_;
friend class Isolate;
};
class RetainedObjectInfo;
......@@ -5227,6 +5245,23 @@ class V8_EXPORT Isolate {
bool GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
size_t index);
/**
* Returns the number of types of objects tracked in the heap at GC.
*/
size_t NumberOfTrackedHeapObjectTypes();
/**
* Get statistics about objects in the heap.
*
* \param object_statistics The HeapObjectStatistics object to fill in
* statistics of objects of given type, which were live in the previous GC.
* \param type_index The index of the type of object to fill details about,
* which ranges from 0 to NumberOfTrackedHeapObjectTypes() - 1.
* \returns true on success.
*/
bool GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics* object_statistics,
size_t type_index);
/**
* Get a call stack sample from the isolate.
* \param state Execution state.
......
......@@ -5346,6 +5346,12 @@ HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0),
physical_space_size_(0) { }
HeapObjectStatistics::HeapObjectStatistics()
: object_type_(nullptr),
object_sub_type_(nullptr),
object_count_(0),
object_size_(0) {}
bool v8::V8::InitializeICU(const char* icu_data_file) {
return i::InitializeICU(icu_data_file);
}
......@@ -6910,6 +6916,38 @@ bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
}
size_t Isolate::NumberOfTrackedHeapObjectTypes() {
return i::Heap::OBJECT_STATS_COUNT;
}
bool Isolate::GetHeapObjectStatisticsAtLastGC(
HeapObjectStatistics* object_statistics, size_t type_index) {
if (!object_statistics) return false;
if (type_index >= i::Heap::OBJECT_STATS_COUNT) return false;
if (!i::FLAG_track_gc_object_stats) return false;
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
i::Heap* heap = isolate->heap();
const char* object_type;
const char* object_sub_type;
size_t object_count = heap->object_count_last_gc(type_index);
size_t object_size = heap->object_size_last_gc(type_index);
if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
// There should be no objects counted when the type is unknown.
DCHECK_EQ(object_count, 0);
DCHECK_EQ(object_size, 0);
return false;
}
object_statistics->object_type_ = object_type;
object_statistics->object_sub_type_ = object_sub_type;
object_statistics->object_count_ = object_count;
object_statistics->object_size_ = object_size;
return true;
}
void Isolate::GetStackSample(const RegisterState& state, void** frames,
size_t frames_limit, SampleInfo* sample_info) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
......
......@@ -6508,5 +6508,43 @@ void Heap::UnregisterStrongRoots(Object** start) {
list = next;
}
}
bool Heap::GetObjectTypeName(size_t index, const char** object_type,
const char** object_sub_type) {
if (index >= OBJECT_STATS_COUNT) return false;
switch (static_cast<int>(index)) {
#define COMPARE_AND_RETURN_NAME(name) \
case name: \
*object_type = #name; \
*object_sub_type = ""; \
return true;
INSTANCE_TYPE_LIST(COMPARE_AND_RETURN_NAME)
#undef COMPARE_AND_RETURN_NAME
#define COMPARE_AND_RETURN_NAME(name) \
case FIRST_CODE_KIND_SUB_TYPE + Code::name: \
*object_type = "CODE_TYPE"; \
*object_sub_type = "CODE_KIND/" #name; \
return true;
CODE_KIND_LIST(COMPARE_AND_RETURN_NAME)
#undef COMPARE_AND_RETURN_NAME
#define COMPARE_AND_RETURN_NAME(name) \
case FIRST_FIXED_ARRAY_SUB_TYPE + name: \
*object_type = "FIXED_ARRAY_TYPE"; \
*object_sub_type = #name; \
return true;
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COMPARE_AND_RETURN_NAME)
#undef COMPARE_AND_RETURN_NAME
#define COMPARE_AND_RETURN_NAME(name) \
case FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge: \
*object_type = "CODE_TYPE"; \
*object_sub_type = "CODE_AGE/" #name; \
return true;
CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME)
#undef COMPARE_AND_RETURN_NAME
}
return false;
}
}
} // namespace v8::internal
......@@ -1026,6 +1026,13 @@ class Heap {
// Print short heap statistics.
void PrintShortHeapStatistics();
size_t object_count_last_gc(size_t index) {
return index < OBJECT_STATS_COUNT ? object_counts_last_time_[index] : 0;
}
size_t object_size_last_gc(size_t index) {
return index < OBJECT_STATS_COUNT ? object_sizes_last_time_[index] : 0;
}
// Write barrier support for address[offset] = o.
INLINE(void RecordWrite(Address address, int offset));
......@@ -1458,6 +1465,8 @@ class Heap {
void TraceObjectStats();
void TraceObjectStat(const char* name, int count, int size, double time);
void CheckpointObjectStats();
bool GetObjectTypeName(size_t index, const char** object_type,
const char** object_sub_type);
void RegisterStrongRoots(Object** start, Object** end);
void UnregisterStrongRoots(Object** start);
......
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