Add support for tracking NotExectuted/ExecutedOnceCodeAge's when...

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
parent 3c8cee2f
...@@ -50,7 +50,9 @@ enum BuiltinExtraArguments { ...@@ -50,7 +50,9 @@ enum BuiltinExtraArguments {
#define CODE_AGE_LIST(V) \ #define CODE_AGE_LIST(V) \
CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, 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) \ V(NoAge) \
CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, V) CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, V)
......
...@@ -7881,17 +7881,18 @@ void Heap::CheckpointObjectStats() { ...@@ -7881,17 +7881,18 @@ void Heap::CheckpointObjectStats() {
static_cast<int>(object_sizes_last_time_[index])); static_cast<int>(object_sizes_last_time_[index]));
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT) FIXED_ARRAY_SUB_INSTANCE_TYPE_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) \ #define ADJUST_LAST_TIME_OBJECT_COUNT(name) \
index = FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge; \ index = \
counters->count_of_CODE_AGE_##name()->Increment( \ FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge; \
static_cast<int>(object_counts_[index])); \ counters->count_of_CODE_AGE_##name()->Increment( \
counters->count_of_CODE_AGE_##name()->Decrement( \ static_cast<int>(object_counts_[index])); \
static_cast<int>(object_counts_last_time_[index])); \ counters->count_of_CODE_AGE_##name()->Decrement( \
counters->size_of_CODE_AGE_##name()->Increment( \ static_cast<int>(object_counts_last_time_[index])); \
static_cast<int>(object_sizes_[index])); \ counters->size_of_CODE_AGE_##name()->Increment( \
counters->size_of_CODE_AGE_##name()->Decrement( \ static_cast<int>(object_sizes_[index])); \
counters->size_of_CODE_AGE_##name()->Decrement( \
static_cast<int>(object_sizes_last_time_[index])); 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 #undef ADJUST_LAST_TIME_OBJECT_COUNT
OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
......
...@@ -1807,7 +1807,7 @@ class Heap { ...@@ -1807,7 +1807,7 @@ class Heap {
FIRST_CODE_KIND_SUB_TYPE + Code::NUMBER_OF_KINDS, FIRST_CODE_KIND_SUB_TYPE + Code::NUMBER_OF_KINDS,
FIRST_CODE_AGE_SUB_TYPE = FIRST_CODE_AGE_SUB_TYPE =
FIRST_FIXED_ARRAY_SUB_TYPE + LAST_FIXED_ARRAY_SUB_TYPE + 1, 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) { void RecordObjectStats(InstanceType type, size_t size) {
...@@ -1817,12 +1817,17 @@ class Heap { ...@@ -1817,12 +1817,17 @@ class Heap {
} }
void RecordCodeSubTypeStats(int code_sub_type, int code_age, size_t size) { void RecordCodeSubTypeStats(int code_sub_type, int code_age, size_t size) {
ASSERT(code_sub_type < Code::NUMBER_OF_KINDS); int code_sub_type_index = FIRST_CODE_KIND_SUB_TYPE + code_sub_type;
ASSERT(code_age < Code::kLastCodeAge); int code_age_index =
object_counts_[FIRST_CODE_KIND_SUB_TYPE + code_sub_type]++; FIRST_CODE_AGE_SUB_TYPE + code_age - Code::kFirstCodeAge;
object_sizes_[FIRST_CODE_KIND_SUB_TYPE + code_sub_type] += size; ASSERT(code_sub_type_index >= FIRST_CODE_KIND_SUB_TYPE &&
object_counts_[FIRST_CODE_AGE_SUB_TYPE + code_age]++; code_sub_type_index < FIRST_CODE_AGE_SUB_TYPE);
object_sizes_[FIRST_CODE_AGE_SUB_TYPE + code_age] += size; 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) { void RecordFixedArraySubTypeStats(int array_sub_type, size_t size) {
......
...@@ -1650,7 +1650,7 @@ class MarkCompactMarkingVisitor::ObjectStatsTracker< ...@@ -1650,7 +1650,7 @@ class MarkCompactMarkingVisitor::ObjectStatsTracker<
int object_size = obj->Size(); int object_size = obj->Size();
ASSERT(map->instance_type() == CODE_TYPE); ASSERT(map->instance_type() == CODE_TYPE);
Code* code_obj = Code::cast(obj); Code* code_obj = Code::cast(obj);
heap->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetAge(), heap->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetRawAge(),
object_size); object_size);
ObjectStatsVisitBase(kVisitCode, map, obj); ObjectStatsVisitBase(kVisitCode, map, obj);
} }
......
...@@ -10663,12 +10663,25 @@ void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) { ...@@ -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) { void Code::MakeOlder(MarkingParity current_parity) {
byte* sequence = FindCodeAgeSequence(); byte* sequence = FindCodeAgeSequence();
if (sequence != NULL) { if (sequence != NULL) {
Age age; Age age;
MarkingParity code_parity; MarkingParity code_parity;
GetCodeAgeAndParity(sequence, &age, &code_parity); GetCodeAgeAndParity(sequence, &age, &code_parity);
age = EffectiveAge(age);
if (age != kLastCodeAge && code_parity != current_parity) { if (age != kLastCodeAge && code_parity != current_parity) {
PatchPlatformCodeAge(GetIsolate(), PatchPlatformCodeAge(GetIsolate(),
sequence, sequence,
...@@ -10680,8 +10693,7 @@ void Code::MakeOlder(MarkingParity current_parity) { ...@@ -10680,8 +10693,7 @@ void Code::MakeOlder(MarkingParity current_parity) {
bool Code::IsOld() { bool Code::IsOld() {
Age age = GetAge(); return GetAge() >= kIsOldCodeAge;
return age >= kIsOldCodeAge;
} }
...@@ -10696,9 +10708,14 @@ byte* Code::FindCodeAgeSequence() { ...@@ -10696,9 +10708,14 @@ byte* Code::FindCodeAgeSequence() {
Code::Age Code::GetAge() { Code::Age Code::GetAge() {
return EffectiveAge(GetRawAge());
}
Code::Age Code::GetRawAge() {
byte* sequence = FindCodeAgeSequence(); byte* sequence = FindCodeAgeSequence();
if (sequence == NULL) { if (sequence == NULL) {
return Code::kNoAgeCodeAge; return kNoAgeCodeAge;
} }
Age age; Age age;
MarkingParity parity; MarkingParity parity;
...@@ -10729,15 +10746,13 @@ void Code::GetCodeAgeAndParity(Code* code, Age* age, ...@@ -10729,15 +10746,13 @@ void Code::GetCodeAgeAndParity(Code* code, Age* age,
#undef HANDLE_CODE_AGE #undef HANDLE_CODE_AGE
stub = *builtins->MarkCodeAsExecutedOnce(); stub = *builtins->MarkCodeAsExecutedOnce();
if (code == stub) { if (code == stub) {
// Treat that's never been executed as old immediatly. *age = kNotExecutedCodeAge;
*age = kIsOldCodeAge;
*parity = NO_MARKING_PARITY; *parity = NO_MARKING_PARITY;
return; return;
} }
stub = *builtins->MarkCodeAsExecutedTwice(); stub = *builtins->MarkCodeAsExecutedTwice();
if (code == stub) { if (code == stub) {
// Pre-age code that has only been executed once. *age = kExecutedOnceCodeAge;
*age = kPreAgedCodeAge;
*parity = NO_MARKING_PARITY; *parity = NO_MARKING_PARITY;
return; return;
} }
......
...@@ -5348,8 +5348,9 @@ class Code: public HeapObject { ...@@ -5348,8 +5348,9 @@ class Code: public HeapObject {
kNoAgeCodeAge = 0, kNoAgeCodeAge = 0,
CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM) CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
kAfterLastCodeAge, kAfterLastCodeAge,
kFirstCodeAge = kNotExecutedCodeAge,
kLastCodeAge = kAfterLastCodeAge - 1, kLastCodeAge = kAfterLastCodeAge - 1,
kCodeAgeCount = kAfterLastCodeAge - 1, kCodeAgeCount = kAfterLastCodeAge - kNotExecutedCodeAge - 1,
kIsOldCodeAge = kSexagenarianCodeAge, kIsOldCodeAge = kSexagenarianCodeAge,
kPreAgedCodeAge = kIsOldCodeAge - 1 kPreAgedCodeAge = kIsOldCodeAge - 1
}; };
...@@ -5365,6 +5366,9 @@ class Code: public HeapObject { ...@@ -5365,6 +5366,9 @@ class Code: public HeapObject {
static bool IsYoungSequence(byte* sequence); static bool IsYoungSequence(byte* sequence);
bool IsOld(); bool IsOld();
Age GetAge(); 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) { static inline Code* GetPreAgedCodeAgeStub(Isolate* isolate) {
return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY); return GetCodeAgeStub(isolate, kNotExecutedCodeAge, NO_MARKING_PARITY);
} }
......
...@@ -82,7 +82,7 @@ Counters::Counters(Isolate* isolate) { ...@@ -82,7 +82,7 @@ Counters::Counters(Isolate* isolate) {
StatsCounter(isolate, "c:" "V8.CountOf_CODE_AGE-" #name); \ StatsCounter(isolate, "c:" "V8.CountOf_CODE_AGE-" #name); \
size_of_CODE_AGE_##name##_ = \ size_of_CODE_AGE_##name##_ = \
StatsCounter(isolate, "c:" "V8.SizeOf_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 #undef SC
} }
......
...@@ -343,7 +343,7 @@ class Counters { ...@@ -343,7 +343,7 @@ class Counters {
{ return &count_of_CODE_AGE_##name##_; } \ { return &count_of_CODE_AGE_##name##_; } \
StatsCounter* size_of_CODE_AGE_##name() \ StatsCounter* size_of_CODE_AGE_##name() \
{ return &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 #undef SC
enum Id { enum Id {
...@@ -373,7 +373,7 @@ class Counters { ...@@ -373,7 +373,7 @@ class Counters {
#undef COUNTER_ID #undef COUNTER_ID
#define COUNTER_ID(name) kCountOfCODE_AGE__##name, \ #define COUNTER_ID(name) kCountOfCODE_AGE__##name, \
kSizeOfCODE_AGE__##name, kSizeOfCODE_AGE__##name,
CODE_AGE_LIST_WITH_NO_AGE(COUNTER_ID) CODE_AGE_LIST_COMPLETE(COUNTER_ID)
#undef COUNTER_ID #undef COUNTER_ID
stats_counter_count stats_counter_count
}; };
...@@ -423,7 +423,7 @@ class Counters { ...@@ -423,7 +423,7 @@ class Counters {
#define SC(name) \ #define SC(name) \
StatsCounter size_of_CODE_AGE_##name##_; \ StatsCounter size_of_CODE_AGE_##name##_; \
StatsCounter count_of_CODE_AGE_##name##_; StatsCounter count_of_CODE_AGE_##name##_;
CODE_AGE_LIST_WITH_NO_AGE(SC) CODE_AGE_LIST_COMPLETE(SC)
#undef SC #undef SC
friend class Isolate; friend class Isolate;
......
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