Skip to content

Commit ea4e143

Browse files
committed
A rejit/rethunk change
1 parent 4628db4 commit ea4e143

File tree

6 files changed

+27
-8
lines changed

6 files changed

+27
-8
lines changed

lib/Backend/BailOut.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ uint32 bailOutOffset, void * returnAddress, IR::BailOutKind bailOutKind, Js::Imp
11501150
sizeof(registerSaves));
11511151

11521152
Js::Var result = BailOutCommonNoCodeGen(layout, bailOutRecord, bailOutOffset, returnAddress, bailOutKind, branchValue, nullptr, bailOutReturnValue, argoutRestoreAddress);
1153-
ScheduleFunctionCodeGen(Js::ScriptFunction::FromVar(layout->functionObject), nullptr, bailOutRecord, bailOutKind, savedImplicitCallFlags, returnAddress);
1153+
ScheduleFunctionCodeGen(Js::ScriptFunction::FromVar(layout->functionObject), nullptr, bailOutRecord, bailOutKind, bailOutOffset, savedImplicitCallFlags, returnAddress);
11541154
return result;
11551155
}
11561156

@@ -1171,7 +1171,7 @@ BailOutRecord::BailOutInlinedCommon(Js::JavascriptCallStackLayout * layout, Bail
11711171
BailOutInlinedHelper(layout, currentBailOutRecord, bailOutOffset, returnAddress, bailOutKind, registerSaves, &bailOutReturnValue, &innerMostInlinee, false, branchValue);
11721172
Js::Var result = BailOutCommonNoCodeGen(layout, currentBailOutRecord, currentBailOutRecord->bailOutOffset, returnAddress, bailOutKind, branchValue,
11731173
registerSaves, &bailOutReturnValue);
1174-
ScheduleFunctionCodeGen(Js::ScriptFunction::FromVar(layout->functionObject), innerMostInlinee, currentBailOutRecord, bailOutKind, savedImplicitCallFlags, returnAddress);
1174+
ScheduleFunctionCodeGen(Js::ScriptFunction::FromVar(layout->functionObject), innerMostInlinee, currentBailOutRecord, bailOutKind, bailOutOffset, savedImplicitCallFlags, returnAddress);
11751175
return result;
11761176
}
11771177

@@ -1750,8 +1750,10 @@ BailOutRecord::BailOutHelper(Js::JavascriptCallStackLayout * layout, Js::ScriptF
17501750
// code we avoid a rejit by checking if the offending optimization has been disabled in the default code and if so
17511751
// we "rethunk" the bailing out function rather that incurring a rejit.
17521752

1753+
// actualBailOutOffset - bail out offset in the function, inlinee or otherwise, that had the bailout.
1754+
17531755
void BailOutRecord::ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee,
1754-
BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind, Js::ImplicitCallFlags savedImplicitCallFlags, void * returnAddress)
1756+
BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind, uint32 actualBailOutOffset, Js::ImplicitCallFlags savedImplicitCallFlags, void * returnAddress)
17551757
{
17561758
if (bailOutKind == IR::BailOnSimpleJitToFullJitLoopBody ||
17571759
bailOutKind == IR::BailOutForGeneratorYield ||
@@ -2216,18 +2218,21 @@ void BailOutRecord::ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::S
22162218
rejitReason = RejitReason::Forced;
22172219
}
22182220

2219-
// REVIEW: Temporary fix for RS1. Disable Rejiting if it looks like it is not fixing the problem.
2220-
// For RS2, turn this into an assert and let's fix all these issues.
22212221
if (!reThunk && rejitReason != RejitReason::None)
22222222
{
2223-
if (executeFunction->GetDynamicProfileInfo()->GetRejitCount() >= 100)
2223+
Js::DynamicProfileInfo * profileInfo = executeFunction->GetAnyDynamicProfileInfo();
2224+
// REVIEW: Temporary fix for RS1. Disable Rejiting if it looks like it is not fixing the problem.
2225+
// For RS2, turn the rejitCount check into an assert and let's fix all these issues.
2226+
if (profileInfo->GetRejitCount() >= 100 ||
2227+
(profileInfo->GetBailOutOffsetForLastRejit() == actualBailOutOffset && function->IsNewEntryPointAvailable()))
22242228
{
22252229
reThunk = true;
22262230
rejitReason = RejitReason::None;
22272231
}
22282232
else
22292233
{
2230-
executeFunction->GetDynamicProfileInfo()->IncRejitCount();
2234+
profileInfo->IncRejitCount();
2235+
profileInfo->SetBailOutOffsetForLastRejit(actualBailOutOffset);
22312236
}
22322237
}
22332238

lib/Backend/BailOut.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,8 @@ class BailOutRecord
253253

254254
static void UpdatePolymorphicFieldAccess(Js::JavascriptFunction * function, BailOutRecord const * bailOutRecord);
255255

256-
static void ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee, BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind, Js::ImplicitCallFlags savedImplicitCallFlags, void * returnAddress);
256+
static void ScheduleFunctionCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee, BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind,
257+
uint32 actualBailOutOffset, Js::ImplicitCallFlags savedImplicitCallFlags, void * returnAddress);
257258
static void ScheduleLoopBodyCodeGen(Js::ScriptFunction * function, Js::ScriptFunction * innerMostInlinee, BailOutRecord const * bailOutRecord, IR::BailOutKind bailOutKind);
258259
static void CheckPreemptiveRejit(Js::FunctionBody* executeFunction, IR::BailOutKind bailOutKind, BailOutRecord* bailoutRecord, uint8& callsOrIterationsCount, int loopNumber);
259260
void RestoreValues(IR::BailOutKind bailOutKind, Js::JavascriptCallStackLayout * layout, Js::InterpreterStackFrame * newInstance, Js::ScriptContext * scriptContext,

lib/Runtime/Language/DynamicProfileInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ namespace Js
189189
}
190190

191191
this->rejitCount = 0;
192+
this->bailOutOffsetForLastRejit = Js::Constants::NoByteCodeOffset;
192193
#if DBG
193194
for (ProfileId i = 0; i < functionBody->GetProfiledArrayCallSiteCount(); ++i)
194195
{

lib/Runtime/Language/DynamicProfileInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ namespace Js
517517

518518
uint32 m_recursiveInlineInfo; // Bit is set for each callsites where the function is called recursively
519519
uint32 polymorphicCacheState;
520+
uint32 bailOutOffsetForLastRejit;
520521
uint16 rejitCount;
521522
BYTE currentInlinerVersion; // Used to detect when inlining profile changes
522523
bool hasFunctionBody;
@@ -810,6 +811,8 @@ namespace Js
810811
static bool IsCallSiteNoInfo(Js::LocalFunctionId functionId) { return functionId == CallSiteNoInfo; }
811812
int IncRejitCount() { return this->rejitCount++; }
812813
int GetRejitCount() { return this->rejitCount; }
814+
void SetBailOutOffsetForLastRejit(uint32 offset) { this->bailOutOffsetForLastRejit = offset; }
815+
uint32 GetBailOutOffsetForLastRejit() { return this->bailOutOffsetForLastRejit; }
813816

814817
#if DBG_DUMP
815818
void Dump(FunctionBody* functionBody, ArenaAllocator * dynamicProfileInfoAllocator = nullptr);

lib/Runtime/Library/ScriptFunction.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,14 @@ namespace Js
330330
return functionBody->GetOriginalEntryPoint();
331331
}
332332

333+
bool ScriptFunction::IsNewEntryPointAvailable()
334+
{
335+
Js::FunctionEntryPointInfo *const defaultEntryPointInfo = this->GetFunctionBody()->GetDefaultFunctionEntryPointInfo();
336+
JavascriptMethod defaultEntryPoint = this->GetFunctionBody()->GetDirectEntryPoint(defaultEntryPointInfo);
337+
338+
return this->GetEntryPoint() != defaultEntryPoint;
339+
}
340+
333341
Var ScriptFunction::GetSourceString() const
334342
{
335343
return this->GetFunctionProxy()->EnsureDeserialized()->GetCachedSourceString();

lib/Runtime/Library/ScriptFunction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ namespace Js
7373

7474
void ChangeEntryPoint(ProxyEntryPointInfo* entryPointInfo, JavascriptMethod entryPoint);
7575
JavascriptMethod UpdateThunkEntryPoint(FunctionEntryPointInfo* entryPointInfo, JavascriptMethod entryPoint);
76+
bool IsNewEntryPointAvailable();
7677
JavascriptMethod UpdateUndeferredBody(FunctionBody* newFunctionInfo);
7778

7879
virtual ScriptFunctionType * DuplicateType() override;

0 commit comments

Comments
 (0)