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:
mstarzinger@chromium.org 2013-11-06 09:29:09 +00:00
parent 3c8cee2f8d
commit 88be0606cf
8 changed files with 58 additions and 31 deletions

View File

@ -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)

View File

@ -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_));

View File

@ -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) {

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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;