Refine object stats for FixedArrays.
R=yangguo@chromium.org Review URL: https://chromiumcodereview.appspot.com/10797008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12165 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8c89cc4cab
commit
0fb5189a32
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2010 the V8 project authors. All rights reserved.
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||||
// Redistribution and use in source and binary forms, with or without
|
// Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are
|
// modification, are permitted provided that the following conditions are
|
||||||
// met:
|
// met:
|
||||||
@ -87,6 +87,16 @@ v8::Handle<v8::Value> StatisticsExtension::GetCounters(
|
|||||||
|
|
||||||
CODE_KIND_LIST(ADD_COUNTER)
|
CODE_KIND_LIST(ADD_COUNTER)
|
||||||
#undef ADD_COUNTER
|
#undef ADD_COUNTER
|
||||||
|
#define ADD_COUNTER(name) \
|
||||||
|
result->Set(v8::String::New("count_of_FIXED_ARRAY_" #name), \
|
||||||
|
v8::Number::New( \
|
||||||
|
*counters->count_of_FIXED_ARRAY_##name()->GetInternalPointer())); \
|
||||||
|
result->Set(v8::String::New("size_of_FIXED_ARRAY_" #name), \
|
||||||
|
v8::Number::New( \
|
||||||
|
*counters->size_of_FIXED_ARRAY_##name()->GetInternalPointer()));
|
||||||
|
|
||||||
|
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADD_COUNTER)
|
||||||
|
#undef ADD_COUNTER
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
12
src/heap.cc
12
src/heap.cc
@ -7224,6 +7224,18 @@ void Heap::CheckpointObjectStats() {
|
|||||||
static_cast<int>(object_sizes_last_time_[index]));
|
static_cast<int>(object_sizes_last_time_[index]));
|
||||||
CODE_KIND_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
|
CODE_KIND_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
|
||||||
#undef ADJUST_LAST_TIME_OBJECT_COUNT
|
#undef ADJUST_LAST_TIME_OBJECT_COUNT
|
||||||
|
#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \
|
||||||
|
index = FIRST_FIXED_ARRAY_SUB_TYPE + name; \
|
||||||
|
counters->count_of_FIXED_ARRAY_##name()->Increment( \
|
||||||
|
static_cast<int>(object_counts_[index])); \
|
||||||
|
counters->count_of_FIXED_ARRAY_##name()->Decrement( \
|
||||||
|
static_cast<int>(object_counts_last_time_[index])); \
|
||||||
|
counters->size_of_FIXED_ARRAY_##name()->Increment( \
|
||||||
|
static_cast<int>(object_sizes_[index])); \
|
||||||
|
counters->size_of_FIXED_ARRAY_##name()->Decrement( \
|
||||||
|
static_cast<int>(object_sizes_last_time_[index]));
|
||||||
|
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
|
||||||
|
#undef ADJUST_LAST_TIME_OBJECT_COUNT
|
||||||
|
|
||||||
memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
|
memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
|
||||||
memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
|
memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
|
||||||
|
@ -1601,7 +1601,10 @@ class Heap {
|
|||||||
// another.
|
// another.
|
||||||
enum {
|
enum {
|
||||||
FIRST_CODE_KIND_SUB_TYPE = LAST_TYPE + 1,
|
FIRST_CODE_KIND_SUB_TYPE = LAST_TYPE + 1,
|
||||||
OBJECT_STATS_COUNT = FIRST_CODE_KIND_SUB_TYPE + Code::LAST_CODE_KIND + 1
|
FIRST_FIXED_ARRAY_SUB_TYPE =
|
||||||
|
FIRST_CODE_KIND_SUB_TYPE + Code::LAST_CODE_KIND + 1,
|
||||||
|
OBJECT_STATS_COUNT =
|
||||||
|
FIRST_FIXED_ARRAY_SUB_TYPE + LAST_FIXED_ARRAY_SUB_TYPE + 1
|
||||||
};
|
};
|
||||||
|
|
||||||
void RecordObjectStats(InstanceType type, int sub_type, size_t size) {
|
void RecordObjectStats(InstanceType type, int sub_type, size_t size) {
|
||||||
@ -1614,6 +1617,10 @@ class Heap {
|
|||||||
ASSERT(sub_type <= Code::LAST_CODE_KIND);
|
ASSERT(sub_type <= Code::LAST_CODE_KIND);
|
||||||
object_counts_[FIRST_CODE_KIND_SUB_TYPE + sub_type]++;
|
object_counts_[FIRST_CODE_KIND_SUB_TYPE + sub_type]++;
|
||||||
object_sizes_[FIRST_CODE_KIND_SUB_TYPE + sub_type] += size;
|
object_sizes_[FIRST_CODE_KIND_SUB_TYPE + sub_type] += size;
|
||||||
|
} else if (type == FIXED_ARRAY_TYPE) {
|
||||||
|
ASSERT(sub_type <= LAST_FIXED_ARRAY_SUB_TYPE);
|
||||||
|
object_counts_[FIRST_FIXED_ARRAY_SUB_TYPE + sub_type]++;
|
||||||
|
object_sizes_[FIRST_FIXED_ARRAY_SUB_TYPE + sub_type] += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -944,7 +944,15 @@ class StaticMarkingVisitor : public StaticVisitorBase {
|
|||||||
table_.GetVisitor(map)(map, obj);
|
table_.GetVisitor(map)(map, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int id>
|
static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id,
|
||||||
|
Map* map, HeapObject* obj);
|
||||||
|
|
||||||
|
static void ObjectStatsCountFixedArray(
|
||||||
|
FixedArrayBase* fixed_array,
|
||||||
|
FixedArraySubInstanceType fast_type,
|
||||||
|
FixedArraySubInstanceType dictionary_type);
|
||||||
|
|
||||||
|
template<StaticMarkingVisitor::VisitorId id>
|
||||||
class ObjectStatsTracker {
|
class ObjectStatsTracker {
|
||||||
public:
|
public:
|
||||||
static inline void Visit(Map* map, HeapObject* obj);
|
static inline void Visit(Map* map, HeapObject* obj);
|
||||||
@ -1499,16 +1507,84 @@ class StaticMarkingVisitor : public StaticVisitorBase {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template<int id>
|
void StaticMarkingVisitor::ObjectStatsCountFixedArray(
|
||||||
void StaticMarkingVisitor::ObjectStatsTracker<id>::Visit(
|
FixedArrayBase* fixed_array,
|
||||||
Map* map, HeapObject* obj) {
|
FixedArraySubInstanceType fast_type,
|
||||||
|
FixedArraySubInstanceType dictionary_type) {
|
||||||
|
Heap* heap = fixed_array->map()->GetHeap();
|
||||||
|
if (fixed_array->map() != heap->fixed_cow_array_map() &&
|
||||||
|
fixed_array->map() != heap->fixed_double_array_map() &&
|
||||||
|
fixed_array != heap->empty_fixed_array()) {
|
||||||
|
if (fixed_array->IsDictionary()) {
|
||||||
|
heap->RecordObjectStats(FIXED_ARRAY_TYPE,
|
||||||
|
dictionary_type,
|
||||||
|
fixed_array->Size());
|
||||||
|
} else {
|
||||||
|
heap->RecordObjectStats(FIXED_ARRAY_TYPE,
|
||||||
|
fast_type,
|
||||||
|
fixed_array->Size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StaticMarkingVisitor::ObjectStatsVisitBase(
|
||||||
|
StaticVisitorBase::VisitorId id, Map* map, HeapObject* obj) {
|
||||||
Heap* heap = map->GetHeap();
|
Heap* heap = map->GetHeap();
|
||||||
int object_size = obj->Size();
|
int object_size = obj->Size();
|
||||||
heap->RecordObjectStats(map->instance_type(), -1, object_size);
|
heap->RecordObjectStats(map->instance_type(), -1, object_size);
|
||||||
non_count_table_.GetVisitorById(static_cast<VisitorId>(id))(map, obj);
|
non_count_table_.GetVisitorById(id)(map, obj);
|
||||||
|
if (obj->IsJSObject()) {
|
||||||
|
JSObject* object = JSObject::cast(obj);
|
||||||
|
ObjectStatsCountFixedArray(object->elements(),
|
||||||
|
DICTIONARY_ELEMENTS_SUB_TYPE,
|
||||||
|
FAST_ELEMENTS_SUB_TYPE);
|
||||||
|
ObjectStatsCountFixedArray(object->properties(),
|
||||||
|
DICTIONARY_PROPERTIES_SUB_TYPE,
|
||||||
|
FAST_PROPERTIES_SUB_TYPE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<StaticMarkingVisitor::VisitorId id>
|
||||||
|
void StaticMarkingVisitor::ObjectStatsTracker<id>::Visit(
|
||||||
|
Map* map, HeapObject* obj) {
|
||||||
|
ObjectStatsVisitBase(id, map, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class StaticMarkingVisitor::ObjectStatsTracker<
|
||||||
|
StaticMarkingVisitor::kVisitMap> {
|
||||||
|
public:
|
||||||
|
static inline void Visit(Map* map, HeapObject* obj) {
|
||||||
|
Heap* heap = map->GetHeap();
|
||||||
|
Map* map_obj = Map::cast(obj);
|
||||||
|
ASSERT(map->instance_type() == MAP_TYPE);
|
||||||
|
DescriptorArray* array = map_obj->instance_descriptors();
|
||||||
|
if (array != heap->empty_descriptor_array()) {
|
||||||
|
int fixed_array_size = array->Size();
|
||||||
|
heap->RecordObjectStats(FIXED_ARRAY_TYPE,
|
||||||
|
DESCRIPTOR_ARRAY_SUB_TYPE,
|
||||||
|
fixed_array_size);
|
||||||
|
}
|
||||||
|
if (map_obj->HasTransitionArray()) {
|
||||||
|
int fixed_array_size = map_obj->transitions()->Size();
|
||||||
|
heap->RecordObjectStats(FIXED_ARRAY_TYPE,
|
||||||
|
TRANSITION_ARRAY_SUB_TYPE,
|
||||||
|
fixed_array_size);
|
||||||
|
}
|
||||||
|
if (map_obj->code_cache() != heap->empty_fixed_array()) {
|
||||||
|
heap->RecordObjectStats(
|
||||||
|
FIXED_ARRAY_TYPE,
|
||||||
|
MAP_CODE_CACHE_SUB_TYPE,
|
||||||
|
FixedArray::cast(map_obj->code_cache())->Size());
|
||||||
|
}
|
||||||
|
ObjectStatsVisitBase(kVisitMap, map, obj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
class StaticMarkingVisitor::ObjectStatsTracker<
|
class StaticMarkingVisitor::ObjectStatsTracker<
|
||||||
StaticMarkingVisitor::kVisitCode> {
|
StaticMarkingVisitor::kVisitCode> {
|
||||||
@ -1517,10 +1593,44 @@ class StaticMarkingVisitor::ObjectStatsTracker<
|
|||||||
Heap* heap = map->GetHeap();
|
Heap* heap = map->GetHeap();
|
||||||
int object_size = obj->Size();
|
int object_size = obj->Size();
|
||||||
ASSERT(map->instance_type() == CODE_TYPE);
|
ASSERT(map->instance_type() == CODE_TYPE);
|
||||||
heap->RecordObjectStats(CODE_TYPE, -1, object_size);
|
|
||||||
heap->RecordObjectStats(CODE_TYPE, Code::cast(obj)->kind(), object_size);
|
heap->RecordObjectStats(CODE_TYPE, Code::cast(obj)->kind(), object_size);
|
||||||
non_count_table_.GetVisitorById(
|
ObjectStatsVisitBase(kVisitCode, map, obj);
|
||||||
static_cast<VisitorId>(kVisitCode))(map, obj);
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class StaticMarkingVisitor::ObjectStatsTracker<
|
||||||
|
StaticMarkingVisitor::kVisitSharedFunctionInfo> {
|
||||||
|
public:
|
||||||
|
static inline void Visit(Map* map, HeapObject* obj) {
|
||||||
|
Heap* heap = map->GetHeap();
|
||||||
|
SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
|
||||||
|
if (sfi->scope_info() != heap->empty_fixed_array()) {
|
||||||
|
heap->RecordObjectStats(
|
||||||
|
FIXED_ARRAY_TYPE,
|
||||||
|
SCOPE_INFO_SUB_TYPE,
|
||||||
|
FixedArray::cast(sfi->scope_info())->Size());
|
||||||
|
}
|
||||||
|
ObjectStatsVisitBase(kVisitSharedFunctionInfo, map, obj);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class StaticMarkingVisitor::ObjectStatsTracker<
|
||||||
|
StaticMarkingVisitor::kVisitFixedArray> {
|
||||||
|
public:
|
||||||
|
static inline void Visit(Map* map, HeapObject* obj) {
|
||||||
|
Heap* heap = map->GetHeap();
|
||||||
|
FixedArray* fixed_array = FixedArray::cast(obj);
|
||||||
|
if (fixed_array == heap->symbol_table()) {
|
||||||
|
heap->RecordObjectStats(
|
||||||
|
FIXED_ARRAY_TYPE,
|
||||||
|
SYMBOL_TABLE_SUB_TYPE,
|
||||||
|
fixed_array->Size());
|
||||||
|
}
|
||||||
|
ObjectStatsVisitBase(kVisitFixedArray, map, obj);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -654,6 +654,25 @@ STATIC_CHECK(ODDBALL_TYPE == Internals::kOddballType);
|
|||||||
STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType);
|
STATIC_CHECK(FOREIGN_TYPE == Internals::kForeignType);
|
||||||
|
|
||||||
|
|
||||||
|
#define FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(V) \
|
||||||
|
V(FAST_ELEMENTS_SUB_TYPE) \
|
||||||
|
V(DICTIONARY_ELEMENTS_SUB_TYPE) \
|
||||||
|
V(FAST_PROPERTIES_SUB_TYPE) \
|
||||||
|
V(DICTIONARY_PROPERTIES_SUB_TYPE) \
|
||||||
|
V(MAP_CODE_CACHE_SUB_TYPE) \
|
||||||
|
V(SCOPE_INFO_SUB_TYPE) \
|
||||||
|
V(SYMBOL_TABLE_SUB_TYPE) \
|
||||||
|
V(DESCRIPTOR_ARRAY_SUB_TYPE) \
|
||||||
|
V(TRANSITION_ARRAY_SUB_TYPE)
|
||||||
|
|
||||||
|
enum FixedArraySubInstanceType {
|
||||||
|
#define DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE(name) name,
|
||||||
|
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE)
|
||||||
|
#undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
|
||||||
|
LAST_FIXED_ARRAY_SUB_TYPE = TRANSITION_ARRAY_SUB_TYPE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum CompareResult {
|
enum CompareResult {
|
||||||
LESS = -1,
|
LESS = -1,
|
||||||
EQUAL = 0,
|
EQUAL = 0,
|
||||||
|
@ -71,6 +71,16 @@ Counters::Counters() {
|
|||||||
CODE_KIND_LIST(SC)
|
CODE_KIND_LIST(SC)
|
||||||
#undef SC
|
#undef SC
|
||||||
|
|
||||||
|
#define SC(name) \
|
||||||
|
StatsCounter count_of_FIXED_ARRAY_##name = { \
|
||||||
|
"c:" "V8.CountOf_FIXED_ARRAY-" #name, NULL, false }; \
|
||||||
|
count_of_FIXED_ARRAY_##name##_ = count_of_FIXED_ARRAY_##name; \
|
||||||
|
StatsCounter size_of_FIXED_ARRAY_##name = { \
|
||||||
|
"c:" "V8.SizeOf_FIXED_ARRAY-" #name, NULL, false }; \
|
||||||
|
size_of_FIXED_ARRAY_##name##_ = size_of_FIXED_ARRAY_##name;
|
||||||
|
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
|
||||||
|
#undef SC
|
||||||
|
|
||||||
StatsCounter state_counters[] = {
|
StatsCounter state_counters[] = {
|
||||||
#define COUNTER_NAME(name) \
|
#define COUNTER_NAME(name) \
|
||||||
{ "c:V8.State" #name, NULL, false },
|
{ "c:V8.State" #name, NULL, false },
|
||||||
|
@ -323,6 +323,14 @@ class Counters {
|
|||||||
CODE_KIND_LIST(SC)
|
CODE_KIND_LIST(SC)
|
||||||
#undef SC
|
#undef SC
|
||||||
|
|
||||||
|
#define SC(name) \
|
||||||
|
StatsCounter* count_of_FIXED_ARRAY_##name() \
|
||||||
|
{ return &count_of_FIXED_ARRAY_##name##_; } \
|
||||||
|
StatsCounter* size_of_FIXED_ARRAY_##name() \
|
||||||
|
{ return &size_of_FIXED_ARRAY_##name##_; }
|
||||||
|
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
|
||||||
|
#undef SC
|
||||||
|
|
||||||
enum Id {
|
enum Id {
|
||||||
#define RATE_ID(name, caption) k_##name,
|
#define RATE_ID(name, caption) k_##name,
|
||||||
HISTOGRAM_TIMER_LIST(RATE_ID)
|
HISTOGRAM_TIMER_LIST(RATE_ID)
|
||||||
@ -341,6 +349,10 @@ class Counters {
|
|||||||
kSizeOfCODE_TYPE_##name,
|
kSizeOfCODE_TYPE_##name,
|
||||||
CODE_KIND_LIST(COUNTER_ID)
|
CODE_KIND_LIST(COUNTER_ID)
|
||||||
#undef COUNTER_ID
|
#undef COUNTER_ID
|
||||||
|
#define COUNTER_ID(name) kCountOfFIXED_ARRAY__##name, \
|
||||||
|
kSizeOfFIXED_ARRAY__##name,
|
||||||
|
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(COUNTER_ID)
|
||||||
|
#undef COUNTER_ID
|
||||||
#define COUNTER_ID(name) k_##name,
|
#define COUNTER_ID(name) k_##name,
|
||||||
STATE_TAG_LIST(COUNTER_ID)
|
STATE_TAG_LIST(COUNTER_ID)
|
||||||
#undef COUNTER_ID
|
#undef COUNTER_ID
|
||||||
@ -380,6 +392,12 @@ class Counters {
|
|||||||
CODE_KIND_LIST(SC)
|
CODE_KIND_LIST(SC)
|
||||||
#undef SC
|
#undef SC
|
||||||
|
|
||||||
|
#define SC(name) \
|
||||||
|
StatsCounter size_of_FIXED_ARRAY_##name##_; \
|
||||||
|
StatsCounter count_of_FIXED_ARRAY_##name##_;
|
||||||
|
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(SC)
|
||||||
|
#undef SC
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
#define COUNTER_ID(name) __##name,
|
#define COUNTER_ID(name) __##name,
|
||||||
STATE_TAG_LIST(COUNTER_ID)
|
STATE_TAG_LIST(COUNTER_ID)
|
||||||
|
Loading…
Reference in New Issue
Block a user