Commit 6b905c3a authored by vogelheim's avatar vogelheim Committed by Commit bot

Implement kToBeExecutedOnceCodeAge.

An initial 'code age' state that will turn into a 'pre-aging' code age only after it was executed the first time.

BUG=470930
LOG=Y

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

Cr-Commit-Position: refs/heads/master@{#28162}
parent 1dd93d96
......@@ -1062,6 +1062,11 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
}
void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
Generate_MarkCodeAsExecutedOnce(masm);
}
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
{
......
......@@ -1058,6 +1058,11 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
}
void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
Generate_MarkCodeAsExecutedOnce(masm);
}
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
{
......
......@@ -28,6 +28,7 @@ enum BuiltinExtraArguments {
CODE_AGE_LIST_WITH_ARG(CODE_AGE_LIST_IGNORE_ARG, V)
#define CODE_AGE_LIST_COMPLETE(V) \
V(ToBeExecutedOnce) \
V(NotExecuted) \
V(ExecutedOnce) \
V(NoAge) \
......@@ -122,6 +123,7 @@ enum BuiltinExtraArguments {
V(OsrAfterStackCheck, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(StackCheck, BUILTIN, UNINITIALIZED, kNoExtraICState) \
\
V(MarkCodeAsToBeExecutedOnce, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(MarkCodeAsExecutedOnce, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(MarkCodeAsExecutedTwice, BUILTIN, UNINITIALIZED, kNoExtraICState) \
CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, V)
......@@ -353,6 +355,7 @@ class Builtins {
CODE_AGE_LIST(DECLARE_CODE_AGE_BUILTIN_GENERATOR)
#undef DECLARE_CODE_AGE_BUILTIN_GENERATOR
static void Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm);
static void Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm);
static void Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm);
......
......@@ -1571,7 +1571,7 @@ class MarkCompactMarkingVisitor::ObjectStatsTracker<
int object_size = obj->Size();
DCHECK(map->instance_type() == CODE_TYPE);
Code* code_obj = Code::cast(obj);
heap->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetRawAge(),
heap->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetAge(),
object_size);
ObjectStatsVisitBase(kVisitCode, map, obj);
}
......
......@@ -804,6 +804,11 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
}
void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
Generate_MarkCodeAsExecutedOnce(masm);
}
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
// Enter an internal frame.
......
......@@ -1087,6 +1087,11 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
}
void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
Generate_MarkCodeAsExecutedOnce(masm);
}
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
{
......
......@@ -1094,6 +1094,11 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
}
void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
Generate_MarkCodeAsExecutedOnce(masm);
}
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
{
......
......@@ -11379,15 +11379,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;
// NextAge defines the Code::Age state transitions during a GC cycle.
static Code::Age NextAge(Code::Age age) {
switch (age) {
case Code::kNotExecutedCodeAge: // Keep, until we've been executed.
case Code::kToBeExecutedOnceCodeAge: // Keep, until we've been executed.
case Code::kLastCodeAge: // Clamp at last Code::Age value.
return age;
case Code::kExecutedOnceCodeAge:
// Pre-age code that has only been executed once.
return static_cast<Code::Age>(Code::kPreAgedCodeAge + 1);
default:
return static_cast<Code::Age>(age + 1); // Default case: Increase age.
}
return age;
}
// IsOldAge defines the collection criteria for a Code object.
static bool IsOldAge(Code::Age age) {
return age >= Code::kIsOldCodeAge || age == Code::kNotExecutedCodeAge;
}
......@@ -11397,6 +11407,15 @@ void Code::MakeYoung(Isolate* isolate) {
}
void Code::MarkToBeExecutedOnce(Isolate* isolate) {
byte* sequence = FindCodeAgeSequence();
if (sequence != NULL) {
PatchPlatformCodeAge(isolate, sequence, kToBeExecutedOnceCodeAge,
NO_MARKING_PARITY);
}
}
void Code::MakeOlder(MarkingParity current_parity) {
byte* sequence = FindCodeAgeSequence();
if (sequence != NULL) {
......@@ -11404,19 +11423,16 @@ void Code::MakeOlder(MarkingParity current_parity) {
MarkingParity code_parity;
Isolate* isolate = GetIsolate();
GetCodeAgeAndParity(isolate, sequence, &age, &code_parity);
age = EffectiveAge(age);
if (age != kLastCodeAge && code_parity != current_parity) {
PatchPlatformCodeAge(isolate,
sequence,
static_cast<Age>(age + 1),
current_parity);
Age next_age = NextAge(age);
if (age != next_age && code_parity != current_parity) {
PatchPlatformCodeAge(isolate, sequence, next_age, current_parity);
}
}
}
bool Code::IsOld() {
return GetAge() >= kIsOldCodeAge;
return IsOldAge(GetAge());
}
......@@ -11431,11 +11447,6 @@ byte* Code::FindCodeAgeSequence() {
Code::Age Code::GetAge() {
return EffectiveAge(GetRawAge());
}
Code::Age Code::GetRawAge() {
byte* sequence = FindCodeAgeSequence();
if (sequence == NULL) {
return kNoAgeCodeAge;
......@@ -11479,6 +11490,12 @@ void Code::GetCodeAgeAndParity(Code* code, Age* age,
*parity = NO_MARKING_PARITY;
return;
}
stub = *builtins->MarkCodeAsToBeExecutedOnce();
if (code == stub) {
*age = kToBeExecutedOnceCodeAge;
*parity = NO_MARKING_PARITY;
return;
}
UNREACHABLE();
}
......@@ -11503,6 +11520,10 @@ Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) {
DCHECK(parity == NO_MARKING_PARITY);
return *builtins->MarkCodeAsExecutedTwice();
}
case kToBeExecutedOnceCodeAge: {
DCHECK(parity == NO_MARKING_PARITY);
return *builtins->MarkCodeAsToBeExecutedOnce();
}
default:
UNREACHABLE();
break;
......
......@@ -5541,14 +5541,15 @@ class Code: public HeapObject {
#define DECLARE_CODE_AGE_ENUM(X) k##X##CodeAge,
enum Age {
kToBeExecutedOnceCodeAge = -3,
kNotExecutedCodeAge = -2,
kExecutedOnceCodeAge = -1,
kNoAgeCodeAge = 0,
CODE_AGE_LIST(DECLARE_CODE_AGE_ENUM)
kAfterLastCodeAge,
kFirstCodeAge = kNotExecutedCodeAge,
kFirstCodeAge = kToBeExecutedOnceCodeAge,
kLastCodeAge = kAfterLastCodeAge - 1,
kCodeAgeCount = kAfterLastCodeAge - kNotExecutedCodeAge - 1,
kCodeAgeCount = kAfterLastCodeAge - kFirstCodeAge - 1,
kIsOldCodeAge = kSexagenarianCodeAge,
kPreAgedCodeAge = kIsOldCodeAge - 1
};
......@@ -5561,13 +5562,11 @@ class Code: public HeapObject {
static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
void MakeYoung(Isolate* isolate);
void MarkToBeExecutedOnce(Isolate* isolate);
void MakeOlder(MarkingParity);
static bool IsYoungSequence(Isolate* isolate, 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);
}
......
......@@ -1072,6 +1072,11 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
}
void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
Generate_MarkCodeAsExecutedOnce(masm);
}
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
{
......
......@@ -859,6 +859,11 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
}
void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
Generate_MarkCodeAsExecutedOnce(masm);
}
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
// Enter an internal frame.
......
......@@ -804,6 +804,11 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
}
void Builtins::Generate_MarkCodeToBeExecutedOnce(MacroAssembler* masm) {
Generate_MarkCodeAsExecutedOnce(masm);
}
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
// Enter an internal frame.
......
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