Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChakraCore servicing update for 19-10 #6302

Merged
merged 5 commits into from
Oct 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Build/NuGet/.pack-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.11.13
1.11.14
7 changes: 7 additions & 0 deletions lib/Backend/BackwardPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2195,6 +2195,13 @@ BackwardPass::DeadStoreTypeCheckBailOut(IR::Instr * instr)
return;
}

// By default, do not do this for stores, as it makes the presence of type checks unpredictable in the forward pass.
// For instance, we can't predict which stores may cause reallocation of aux slots.
if (instr->GetDst() && instr->GetDst()->IsSymOpnd())
{
return;
}

IR::BailOutKind oldBailOutKind = instr->GetBailOutKind();
if (!IR::IsTypeCheckBailOutKind(oldBailOutKind))
{
Expand Down
67 changes: 53 additions & 14 deletions lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2161,27 +2161,46 @@ GlobOpt::CollectMemOpInfo(IR::Instr *instrBegin, IR::Instr *instr, Value *src1Va
return false;
}
break;
case Js::OpCode::Decr_A:
isIncr = false;
case Js::OpCode::Incr_A:
isChangedByOne = true;
goto MemOpCheckInductionVariable;
case Js::OpCode::Sub_I4:
case Js::OpCode::Sub_A:
isIncr = false;
case Js::OpCode::Add_A:
case Js::OpCode::Add_I4:
{
MemOpCheckInductionVariable:
StackSym *sym = instr->GetSrc1()->GetStackSym();
if (!sym)
// The only case in which these OpCodes can contribute to an inductionVariableChangeInfo
// is when the induction variable is being modified and overwritten aswell (ex: j = j + 1)
// and not when the induction variable is modified but not overwritten (ex: k = j + 1).
// This can either be detected in IR as
// s1 = Add_I4 s1 1 // Case #1, can be seen with "j++".
// or as
// s4(s2) = Add_I4 s3(s1) 1 // Case #2, can be see with "j = j + 1".
// s1 = Ld_A s2
bool isInductionVar = false;
IR::Instr* nextInstr = instr->m_next;
if (
// Checks for Case #1 and Case #2
instr->GetDst()->GetStackSym() != nullptr &&
instr->GetDst()->IsRegOpnd() &&
(
// Checks for Case #1
(instr->GetDst()->GetStackSym() == instr->GetSrc1()->GetStackSym()) ||

// Checks for Case #2
(nextInstr&& nextInstr->m_opcode == Js::OpCode::Ld_A &&
nextInstr->GetSrc1()->IsRegOpnd() &&
nextInstr->GetDst()->IsRegOpnd() &&
GetVarSymID(instr->GetDst()->GetStackSym()) == nextInstr->GetSrc1()->GetStackSym()->m_id &&
GetVarSymID(instr->GetSrc1()->GetStackSym()) == nextInstr->GetDst()->GetStackSym()->m_id)
)
)
{
sym = instr->GetSrc2()->GetStackSym();
isInductionVar = true;
}

// Even if dstIsInductionVar then dst == src1 so it's safe to use src1 as the induction sym always.
StackSym* sym = instr->GetSrc1()->GetStackSym();

SymID inductionSymID = GetVarSymID(sym);

if (IsSymIDInductionVariable(inductionSymID, this->currentBlock->loop))
if (isInductionVar && IsSymIDInductionVariable(inductionSymID, this->currentBlock->loop))
{
if (!isChangedByOne)
{
Expand Down Expand Up @@ -2246,7 +2265,6 @@ GlobOpt::CollectMemOpInfo(IR::Instr *instrBegin, IR::Instr *instr, Value *src1Va
{
inductionVariableChangeInfo.unroll++;
}

inductionVariableChangeInfo.isIncremental = isIncr;
loop->memOpInfo->inductionVariableChangeInfoMap->Item(inductionSymID, inductionVariableChangeInfo);
}
Expand Down Expand Up @@ -2284,6 +2302,27 @@ GlobOpt::CollectMemOpInfo(IR::Instr *instrBegin, IR::Instr *instr, Value *src1Va
}
}
NEXT_INSTR_IN_RANGE;
IR::Instr* prevInstr = instr->m_prev;

// If an instr where the dst is an induction variable (and thus is being written to) is not caught by a case in the above
// switch statement (which implies that this instr does not contributes to a inductionVariableChangeInfo) and in the default
// case does not set doMemOp to false (which implies that this instr does not invalidate this MemOp), then FailFast as we
// should not be performing a MemOp under these conditions.
AssertOrFailFast(!instr->GetDst() || instr->m_opcode == Js::OpCode::IncrLoopBodyCount || !loop->memOpInfo ||

// Refer to "Case #2" described above in this function. For the following IR:
// Line #1: s4(s2) = Add_I4 s3(s1) 1
// Line #2: s3(s1) = Ld_A s4(s2)
// do not consider line #2 as a violating instr
(instr->m_opcode == Js::OpCode::Ld_I4 &&
prevInstr && (prevInstr->m_opcode == Js::OpCode::Add_I4 || prevInstr->m_opcode == Js::OpCode::Sub_I4) &&
instr->GetSrc1()->IsRegOpnd() &&
instr->GetDst()->IsRegOpnd() &&
prevInstr->GetDst()->IsRegOpnd() &&
instr->GetDst()->GetStackSym() == prevInstr->GetSrc1()->GetStackSym() &&
instr->GetSrc1()->GetStackSym() == prevInstr->GetDst()->GetStackSym()) ||

!loop->memOpInfo->inductionVariableChangeInfoMap->ContainsKey(GetVarSymID(instr->GetDst()->GetStackSym())));
}

return true;
Expand Down Expand Up @@ -3564,7 +3603,7 @@ GlobOpt::OptSrc(IR::Opnd *opnd, IR::Instr * *pInstr, Value **indirIndexValRef, I

opnd->SetValueType(valueType);

if(!IsLoopPrePass() && opnd->IsSymOpnd() && valueType.IsDefinite())
if(!IsLoopPrePass() && opnd->IsSymOpnd() && (valueType.IsDefinite() || valueType.IsNotTaggedValue()))
{
if (opnd->AsSymOpnd()->m_sym->IsPropertySym())
{
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/GlobOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ class JsArrayKills
(valueType.IsArrayOrObjectWithArray() &&
(
(killsArraysWithNoMissingValues && valueType.HasNoMissingValues()) ||
(killsObjectArraysWithNoMissingValues && !valueType.IsArray() && valueType.HasNoMissingValues()) ||
(killsNativeArrays && !valueType.HasVarElements())
)
);
Expand Down
23 changes: 18 additions & 5 deletions lib/Backend/GlobOptFields.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -905,7 +905,7 @@ GlobOpt::FinishOptPropOp(IR::Instr *instr, IR::PropertySymOpnd *opnd, BasicBlock

SymID opndId = opnd->HasObjectTypeSym() ? opnd->GetObjectTypeSym()->m_id : -1;

if (!isObjTypeChecked)
if (!isObjTypeSpecialized || opnd->IsBeingAdded())
{
if (block->globOptData.maybeWrittenTypeSyms == nullptr)
{
Expand Down Expand Up @@ -1122,6 +1122,19 @@ GlobOpt::ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd
Assert(opnd->IsTypeCheckSeqCandidate());
Assert(opnd->HasObjectTypeSym());

if (opnd->HasTypeMismatch())
{
if (emitsTypeCheckOut != nullptr)
{
*emitsTypeCheckOut = false;
}
if (changesTypeValueOut != nullptr)
{
*changesTypeValueOut = false;
}
return false;
}

bool isStore = opnd == instr->GetDst();
bool isTypeDead = opnd->IsTypeDead();
bool consumeType = makeChanges && !IsLoopPrePass();
Expand Down Expand Up @@ -1229,7 +1242,7 @@ GlobOpt::ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd
// a new type value here.
isSpecialized = false;

if (consumeType)
if (makeChanges)
{
opnd->SetTypeMismatch(true);
}
Expand Down Expand Up @@ -1273,7 +1286,7 @@ GlobOpt::ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd
// a new type value here.
isSpecialized = false;

if (consumeType)
if (makeChanges)
{
opnd->SetTypeMismatch(true);
}
Expand Down Expand Up @@ -1324,7 +1337,7 @@ GlobOpt::ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd
{
// Indicates failure/mismatch
isSpecialized = false;
if (consumeType)
if (makeChanges)
{
opnd->SetTypeMismatch(true);
}
Expand Down Expand Up @@ -1423,7 +1436,7 @@ GlobOpt::ProcessPropOpInTypeCheckSeq(IR::Instr* instr, IR::PropertySymOpnd *opnd
// a new type value here.
isSpecialized = false;

if (consumeType)
if (makeChanges)
{
opnd->SetTypeMismatch(true);
}
Expand Down
5 changes: 1 addition & 4 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7420,9 +7420,6 @@ Lowerer::GenerateStFldWithCachedType(IR::Instr *instrStFld, bool* continueAsHelp

if (hasTypeCheckBailout)
{
AssertMsg(PHASE_ON1(Js::ObjTypeSpecIsolatedFldOpsWithBailOutPhase) || !propertySymOpnd->IsTypeDead() || propertySymOpnd->TypeCheckRequired(),
"Why does a field store have a type check bailout, if its type is dead?");

if (instrStFld->GetBailOutInfo()->bailOutInstr != instrStFld)
{
// Set the cache index in the bailout info so that the generated code will write it into the
Expand Down Expand Up @@ -7482,7 +7479,7 @@ Lowerer::GenerateCachedTypeCheck(IR::Instr *instrChk, IR::PropertySymOpnd *prope
// cache and no type check bailout. In the latter case, we can wind up doing expensive failed equivalence checks
// repeatedly and never rejit.
bool doEquivTypeCheck =
(instrChk->HasEquivalentTypeCheckBailOut() && propertySymOpnd->TypeCheckRequired()) ||
(instrChk->HasEquivalentTypeCheckBailOut() && (propertySymOpnd->TypeCheckRequired() || propertySymOpnd == instrChk->GetDst())) ||
(propertySymOpnd->HasEquivalentTypeSet() &&
!(propertySymOpnd->HasFinalType() && propertySymOpnd->HasInitialType()) &&
!propertySymOpnd->MustDoMonoCheck() &&
Expand Down
2 changes: 1 addition & 1 deletion lib/Common/ChakraCoreVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// ChakraCore version number definitions (used in ChakraCore binary metadata)
#define CHAKRA_CORE_MAJOR_VERSION 1
#define CHAKRA_CORE_MINOR_VERSION 11
#define CHAKRA_CORE_PATCH_VERSION 13
#define CHAKRA_CORE_PATCH_VERSION 14
#define CHAKRA_CORE_VERSION_RELEASE_QFE 0 // Redundant with PATCH_VERSION. Keep this value set to 0.

// -------------
Expand Down
17 changes: 17 additions & 0 deletions test/fieldopts/OS23440664.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//Reduced Switches: -printsystemexception -maxinterpretcount:1 -maxsimplejitruncount:1 -werexceptionsupport -oopjit- -bvt -off:bailonnoprofile -force:fixdataprops -forcejitloopbody
var shouldBailout = false;
var IntArr0 = [];
function test0() {
var loopInvariant = shouldBailout;
function makeArrayLength() {
return Math.floor();
}
makeArrayLength();
makeArrayLength();
prop0 = 1;
Object;
for (; shouldBailout ? (Object()) : (IntArr0[Object & 1] = '') ? Object : 0;) {
}
}
test0();
WScript.Echo('pass');
6 changes: 6 additions & 0 deletions test/fieldopts/rlexe.xml
Original file line number Diff line number Diff line change
Expand Up @@ -852,4 +852,10 @@
<files>argobjlengthhoist.js</files>
</default>
</test>
<test>
<default>
<files>OS23440664.js</files>
<compile-flags>-off:bailonnoprofile -force:fixdataprops -forcejitloopbody</compile-flags>
</default>
</test>
</regress-exe>