Add support for tracking NotExectuted/ExecutedOnceCodeAge's when --track_gc_object_stats flag is set.
BUG=None R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/40003002 Patch from Ross McIlroy <rmcilroy@chromium.org>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17513 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
3c8cee2f8d
commit
88be0606cf
@ -50,7 +50,9 @@ enum BuiltinExtraArguments {
|
||||
#define CODE_AGE_LIST(V) \
|
||||
CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, V)
|
||||
|
||||
#define CODE_AGE_LIST_WITH_NO_AGE(V) \
|
||||
#define CODE_AGE_LIST_COMPLETE(V) \
|
||||
V(NotExecuted) \
|
||||
V(ExecutedOnce) \
|
||||
V(NoAge) \
|
||||
CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, V)
|
||||
|
||||
|
21
src/heap.cc
21
src/heap.cc
@ -7881,17 +7881,18 @@ void Heap::CheckpointObjectStats() {
|
||||
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
|
||||
#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \
|
||||
index = FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge; \
|
||||
counters->count_of_CODE_AGE_##name()->Increment( \
|
||||
static_cast<int>(object_counts_[index])); \
|
||||
counters->count_of_CODE_AGE_##name()->Decrement( \
|
||||
static_cast<int>(object_counts_last_time_[index])); \
|
||||
counters->size_of_CODE_AGE_##name()->Increment( \
|
||||
static_cast<int>(object_sizes_[index])); \
|
||||
counters->size_of_CODE_AGE_##name()->Decrement( \
|
||||
#define ADJUST_LAST_TIME_OBJECT_COUNT(name) \
|
||||
index = \
|
||||
FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge; \
|
||||
counters->count_of_CODE_AGE_##name()->Increment( \
|
||||
static_cast<int>(object_counts_[index])); \
|
||||
counters->count_of_CODE_AGE_##name()->Decrement( \
|
||||
static_cast<int>(object_counts_last_time_[index])); \
|
||||
counters->size_of_CODE_AGE_##name()->Increment( \
|
||||
static_cast<int>(object_sizes_[index])); \
|
||||
counters->size_of_CODE_AGE_##name()->Decrement( \
|
||||
static_cast<int>(object_sizes_last_time_[index]));
|
||||
CODE_AGE_LIST_WITH_NO_AGE(ADJUST_LAST_TIME_OBJECT_COUNT)
|
||||
CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
|
||||
#undef ADJUST_LAST_TIME_OBJECT_COUNT
|
||||
|
||||
OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
|
||||
|
19
src/heap.h
19
src/heap.h
@ -1807,7 +1807,7 @@ class Heap {
|
||||
FIRST_CODE_KIND_SUB_TYPE + Code::NUMBER_OF_KINDS,
|
||||
FIRST_CODE_AGE_SUB_TYPE =
|
||||
FIRST_FIXED_ARRAY_SUB_TYPE + LAST_FIXED_ARRAY_SUB_TYPE + 1,
|
||||
OBJECT_STATS_COUNT = FIRST_CODE_AGE_SUB_TYPE + Code::kLastCodeAge + 1
|
||||
OBJECT_STATS_COUNT = FIRST_CODE_AGE_SUB_TYPE + Code::kCodeAgeCount + 1
|
||||
};
|
||||
|
||||
void RecordObjectStats(InstanceType type, size_t size) {
|
||||
@ -1817,12 +1817,17 @@ class Heap {
|
||||
}
|
||||
|
||||
void RecordCodeSubTypeStats(int code_sub_type, int code_age, size_t size) {
|
||||
ASSERT(code_sub_type < Code::NUMBER_OF_KINDS);
|
||||
ASSERT(code_age < Code::kLastCodeAge);
|
||||
object_counts_[FIRST_CODE_KIND_SUB_TYPE + code_sub_type]++;
|
||||
object_sizes_[FIRST_CODE_KIND_SUB_TYPE + code_sub_type] += size;
|
||||
object_counts_[FIRST_CODE_AGE_SUB_TYPE + code_age]++;
|
||||
object_sizes_[FIRST_CODE_AGE_SUB_TYPE + code_age] += size;
|
||||
int code_sub_type_index = FIRST_CODE_KIND_SUB_TYPE + code_sub_type;
|
||||
int code_age_index =
|
||||
FIRST_CODE_AGE_SUB_TYPE + code_age - Code::kFirstCodeAge;
|
||||
ASSERT(code_sub_type_index >= FIRST_CODE_KIND_SUB_TYPE &&
|
||||
code_sub_type_index < FIRST_CODE_AGE_SUB_TYPE);
|
||||
ASSERT(code_age_index >= FIRST_CODE_AGE_SUB_TYPE &&
|
||||
code_age_index < OBJECT_STATS_COUNT);
|
||||
object_counts_[code_sub_type_index]++;
|
||||
object_sizes_[code_sub_type_index] += size;
|
||||
object_counts_[code_age_index]++;
|
||||
object_sizes_[code_age_index] += size;
|
||||
}
|
||||
|
||||
void RecordFixedArraySubTypeStats(int array_sub_type, size_t size) {
|
||||
|
@ -1650,7 +1650,7 @@ class MarkCompactMarkingVisitor::ObjectStatsTracker<
|
||||
int object_size = obj->Size();
|
||||
ASSERT(map->instance_type() == CODE_TYPE);
|
||||
Code* code_obj = Code::cast(obj);
|
||||
heap->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetAge(),
|
||||
heap->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetRawAge(),
|
||||
object_size);
|
||||
ObjectStatsVisitBase(kVisitCode, map, obj);
|
||||
}
|
||||
|
@ -10663,12 +10663,25 @@ void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) {
|
||||
}
|
||||
|
||||
|
||||
static Code::Age EffectiveAge(Code::Age age) {
|
||||
if (age == Code::kNotExecutedCodeAge) {
|
||||
// Treat that's never been executed as old immediately.
|
||||
age = Code::kIsOldCodeAge;
|
||||
} else if (age == Code::kExecutedOnceCodeAge) {
|
||||
// Pre-age code that has only been executed once.
|
||||
age = Code::kPreAgedCodeAge;
|
||||
}
|
||||
return age;
|
||||
}
|
||||
|
||||
|
||||
void Code::MakeOlder(MarkingParity current_parity) {
|
||||
byte* sequence = FindCodeAgeSequence();
|
||||
if (sequence != NULL) {
|
||||
Age age;
|
||||
MarkingParity code_parity;
|
||||
GetCodeAgeAndParity(sequence, &age, &code_parity);
|
||||
age = EffectiveAge(age);
|
||||
if (age != kLastCodeAge && code_parity != current_parity) {
|
||||
PatchPlatformCodeAge(GetIsolate(),
|
||||
sequence,
|
||||
@ -10680,8 +10693,7 @@ void Code::MakeOlder(MarkingParity current_parity) {
|
||||
|
||||
|
||||
bool Code::IsOld() {
|
||||
Age age = GetAge();
|
||||
return age >= kIsOldCodeAge;
|
||||
return GetAge() >= kIsOldCodeAge;
|
||||
}
|
||||
|
||||
|
||||
@ -10696,9 +10708,14 @@ byte* Code::FindCodeAgeSequence() {
|
||||
|
||||
|
||||
Code::Age Code::GetAge() {
|
||||
return EffectiveAge(GetRawAge());
|
||||
}
|
||||
|
||||
|
||||
Code::Age Code::GetRawAge() {
|
||||
byte* sequence = FindCodeAgeSequence();
|
||||
if (sequence == NULL) {
|
||||
return Code::kNoAgeCodeAge;
|
||||
return kNoAgeCodeAge;
|
||||
}
|
||||
Age age;
|
||||
MarkingParity parity;
|
||||
@ -10729,15 +10746,13 @@ void Code::GetCodeAgeAndParity(Code* code, Age* age,
|
||||
#undef HANDLE_CODE_AGE
|
||||
stub = *builtins->MarkCodeAsExecutedOnce();
|
||||
if (code == stub) {
|
||||
// Treat that's never been executed as old immediatly.
|
||||
*age = kIsOldCodeAge;
|
||||
*age = kNotExecutedCodeAge;
|
||||
*parity = NO_MARKING_PARITY;
|
||||
return;
|
||||
}
|
||||
stub = *builtins->MarkCodeAsExecutedTwice();
|
||||
if (code == stub) {
|
||||
// Pre-age code that has only been executed once.
|
||||
*age = kPreAgedCodeAge;
|
||||
*age = kExecutedOnceCodeAge;
|
||||
*parity = NO_MARKING_PARITY;
|
||||
return;
|
||||
}
|
||||
|
@ -5348,8 +5348,9 @@ class Code: public HeapObject {
|
||||
kNoAgeCodeAge = 0,
|
||||
CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
|
||||
kAfterLastCodeAge,
|
||||
kFirstCodeAge = kNotExecutedCodeAge,
|
||||
kLastCodeAge = kAfterLastCodeAge - 1,
|
||||
kCodeAgeCount = kAfterLastCodeAge - 1,
|
||||
kCodeAgeCount = kAfterLastCodeAge - kNotExecutedCodeAge - 1,
|
||||
kIsOldCodeAge = kSexagenarianCodeAge,
|
||||
kPreAgedCodeAge = kIsOldCodeAge - 1
|
||||
};
|
||||
@ -5365,6 +5366,9 @@ class Code: public HeapObject {
|
||||
static bool IsYoungSequence(byte* sequence);
|
||||
bool IsOld();
|
||||
Age GetAge();
|
||||
// Gets the raw code age, including psuedo code-age values such as
|
||||
// kNotExecutedCodeAge and kExecutedOnceCodeAge.
|
||||
Age GetRawAge();
|
||||
static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
|
||||
return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ Counters::Counters(Isolate* isolate) {
|
||||
StatsCounter(isolate, "c:" "V8.CountOf_CODE_AGE-" #name); \
|
||||
size_of_CODE_AGE_##name##_ = \
|
||||
StatsCounter(isolate, "c:" "V8.SizeOf_CODE_AGE-" #name);
|
||||
CODE_AGE_LIST_WITH_NO_AGE(SC)
|
||||
CODE_AGE_LIST_COMPLETE(SC)
|
||||
#undef SC
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ class Counters {
|
||||
{ return &count_of_CODE_AGE_##name##_; } \
|
||||
StatsCounter* size_of_CODE_AGE_##name() \
|
||||
{ return &size_of_CODE_AGE_##name##_; }
|
||||
CODE_AGE_LIST_WITH_NO_AGE(SC)
|
||||
CODE_AGE_LIST_COMPLETE(SC)
|
||||
#undef SC
|
||||
|
||||
enum Id {
|
||||
@ -373,7 +373,7 @@ class Counters {
|
||||
#undef COUNTER_ID
|
||||
#define COUNTER_ID(name) kCountOfCODE_AGE__##name, \
|
||||
kSizeOfCODE_AGE__##name,
|
||||
CODE_AGE_LIST_WITH_NO_AGE(COUNTER_ID)
|
||||
CODE_AGE_LIST_COMPLETE(COUNTER_ID)
|
||||
#undef COUNTER_ID
|
||||
stats_counter_count
|
||||
};
|
||||
@ -423,7 +423,7 @@ class Counters {
|
||||
#define SC(name) \
|
||||
StatsCounter size_of_CODE_AGE_##name##_; \
|
||||
StatsCounter count_of_CODE_AGE_##name##_;
|
||||
CODE_AGE_LIST_WITH_NO_AGE(SC)
|
||||
CODE_AGE_LIST_COMPLETE(SC)
|
||||
#undef SC
|
||||
|
||||
friend class Isolate;
|
||||
|
Loading…
Reference in New Issue
Block a user