@@ -1061,9 +1061,6 @@ GlobOpt::MergePredBlocksValueMaps(BasicBlock *block)
1061
1061
this->KillAllObjectTypes();
1062
1062
}
1063
1063
1064
- this->blockData.capturedArgs = JitAnew(this->alloc, BVSparse<JitArenaAllocator>, this->alloc);
1065
- this->blockData.changedSyms = JitAnew(this->alloc, BVSparse<JitArenaAllocator>, this->alloc);
1066
-
1067
1064
this->CopyBlockData(&block->globOptData, &this->blockData);
1068
1065
1069
1066
if (this->IsLoopPrePass())
@@ -1513,7 +1510,6 @@ GlobOpt::NulloutBlockData(GlobOptBlockData *data)
1513
1510
data->stackLiteralInitFldDataMap = nullptr;
1514
1511
1515
1512
data->capturedValues = nullptr;
1516
- data->capturedArgs = nullptr;
1517
1513
data->changedSyms = nullptr;
1518
1514
1519
1515
data->OnDataUnreferenced();
@@ -1562,6 +1558,8 @@ GlobOpt::InitBlockData()
1562
1558
1563
1559
data->stackLiteralInitFldDataMap = nullptr;
1564
1560
1561
+ data->changedSyms = JitAnew(alloc, BVSparse<JitArenaAllocator>, alloc);
1562
+
1565
1563
data->OnDataInitialized(alloc);
1566
1564
}
1567
1565
@@ -1610,9 +1608,7 @@ GlobOpt::ReuseBlockData(GlobOptBlockData *toData, GlobOptBlockData *fromData)
1610
1608
1611
1609
toData->stackLiteralInitFldDataMap = fromData->stackLiteralInitFldDataMap;
1612
1610
1613
- toData->capturedArgs = fromData->capturedArgs;
1614
1611
toData->changedSyms = fromData->changedSyms;
1615
- toData->capturedArgs->ClearAll();
1616
1612
toData->changedSyms->ClearAll();
1617
1613
1618
1614
toData->OnDataReused(fromData);
@@ -1651,9 +1647,7 @@ GlobOpt::CopyBlockData(GlobOptBlockData *toData, GlobOptBlockData *fromData)
1651
1647
toData->inlinedArgOutCount = fromData->inlinedArgOutCount;
1652
1648
toData->hasCSECandidates = fromData->hasCSECandidates;
1653
1649
1654
- toData->capturedArgs = fromData->capturedArgs;
1655
1650
toData->changedSyms = fromData->changedSyms;
1656
- toData->capturedArgs->ClearAll();
1657
1651
toData->changedSyms->ClearAll();
1658
1652
1659
1653
toData->stackLiteralInitFldDataMap = fromData->stackLiteralInitFldDataMap;
@@ -1769,6 +1763,9 @@ void GlobOpt::CloneBlockData(BasicBlock *const toBlock, GlobOptBlockData *const
1769
1763
toData->stackLiteralInitFldDataMap = nullptr;
1770
1764
}
1771
1765
1766
+ toData->changedSyms = JitAnew(alloc, BVSparse<JitArenaAllocator>, alloc);
1767
+ toData->changedSyms->Copy(fromData->changedSyms);
1768
+
1772
1769
Assert(fromData->HasData());
1773
1770
toData->OnDataInitialized(alloc);
1774
1771
}
@@ -1829,6 +1826,60 @@ GlobOpt::CloneValues(BasicBlock *const toBlock, GlobOptBlockData *toData, GlobOp
1829
1826
ProcessValueKills(toBlock, toData);
1830
1827
}
1831
1828
1829
+ template <typename CapturedList, typename CapturedItemsAreEqual>
1830
+ void
1831
+ GlobOpt::MergeCapturedValues(
1832
+ GlobOptBlockData * toData,
1833
+ SListBase<CapturedList> * toList,
1834
+ SListBase<CapturedList> * fromList,
1835
+ CapturedItemsAreEqual itemsAreEqual)
1836
+ {
1837
+ SListBase<CapturedList>::Iterator iterTo(toList);
1838
+ SListBase<CapturedList>::Iterator iterFrom(fromList);
1839
+ bool hasTo = iterTo.Next();
1840
+ bool hasFrom = fromList == nullptr ? false : iterFrom.Next();
1841
+
1842
+ // to be conservative, only copy the captured value for common sym Ids
1843
+ // in from and to CapturedList, mark all non-common sym Ids for re-capture
1844
+ while (hasFrom && hasTo)
1845
+ {
1846
+ Sym * symFrom = iterFrom.Data().Key();
1847
+ Sym * symTo = iterTo.Data().Key();
1848
+
1849
+ if (symFrom->m_id < symTo->m_id)
1850
+ {
1851
+ toData->changedSyms->Set(symFrom->m_id);
1852
+ hasFrom = iterFrom.Next();
1853
+ }
1854
+ else if(symFrom->m_id > symTo->m_id)
1855
+ {
1856
+ toData->changedSyms->Set(symTo->m_id);
1857
+ hasTo = iterTo.Next();
1858
+ }
1859
+ else
1860
+ {
1861
+ if (!itemsAreEqual(&iterFrom.Data(), &iterTo.Data()))
1862
+ {
1863
+ toData->changedSyms->Set(symTo->m_id);
1864
+ }
1865
+
1866
+ hasFrom = iterFrom.Next();
1867
+ hasTo = iterTo.Next();
1868
+ }
1869
+ }
1870
+ bool hasRemain = hasFrom || hasTo;
1871
+ if (hasRemain)
1872
+ {
1873
+ SListBase<CapturedList>::Iterator iterRemain(hasFrom ? iterFrom : iterTo);
1874
+ do
1875
+ {
1876
+ Sym * symRemain = iterRemain.Data().Key();
1877
+ toData->changedSyms->Set(symRemain->m_id);
1878
+ hasRemain = iterRemain.Next();
1879
+ } while (hasRemain);
1880
+ }
1881
+ }
1882
+
1832
1883
void
1833
1884
GlobOpt::MergeBlockData(
1834
1885
GlobOptBlockData *toData,
@@ -1856,6 +1907,39 @@ GlobOpt::MergeBlockData(
1856
1907
toData->isTempSrc->And(fromData->isTempSrc);
1857
1908
toData->hasCSECandidates &= fromData->hasCSECandidates;
1858
1909
1910
+ if (toData->capturedValues == nullptr)
1911
+ {
1912
+ toData->capturedValues = fromData->capturedValues;
1913
+ toData->changedSyms->Or(fromData->changedSyms);
1914
+ }
1915
+ else
1916
+ {
1917
+ MergeCapturedValues(
1918
+ toData,
1919
+ &toData->capturedValues->constantValues,
1920
+ fromData->capturedValues == nullptr ? nullptr : &fromData->capturedValues->constantValues,
1921
+ [&](ConstantStackSymValue * symValueFrom, ConstantStackSymValue * symValueTo)
1922
+ {
1923
+ return symValueFrom->Value().IsEqual(symValueTo->Value());
1924
+ });
1925
+
1926
+ MergeCapturedValues(
1927
+ toData,
1928
+ &toData->capturedValues->copyPropSyms,
1929
+ fromData->capturedValues == nullptr ? nullptr : &fromData->capturedValues->copyPropSyms,
1930
+ [&](CopyPropSyms * copyPropSymFrom, CopyPropSyms * copyPropSymTo)
1931
+ {
1932
+ if (copyPropSymFrom->Value()->m_id == copyPropSymTo->Value()->m_id)
1933
+ {
1934
+ Value * val = FindValue(copyPropSymFrom->Key());
1935
+ Value * copyVal = FindValue(copyPropSymTo->Key());
1936
+ return (val != nullptr && copyVal != nullptr &&
1937
+ val->GetValueNumber() == copyVal->GetValueNumber());
1938
+ }
1939
+ return false;
1940
+ });
1941
+ }
1942
+
1859
1943
if (fromData->maybeWrittenTypeSyms)
1860
1944
{
1861
1945
if (toData->maybeWrittenTypeSyms == nullptr)
@@ -2269,6 +2353,8 @@ GlobOpt::DeleteBlockData(GlobOptBlockData *data)
2269
2353
JitAdelete(alloc, data->stackLiteralInitFldDataMap);
2270
2354
}
2271
2355
2356
+ JitAdelete(alloc, data->changedSyms);
2357
+
2272
2358
data->OnDataDeleted();
2273
2359
}
2274
2360
@@ -5080,7 +5166,6 @@ GlobOpt::OptInstr(IR::Instr *&instr, bool* isInstrRemoved)
5080
5166
5081
5167
if (instr->HasBailOutInfo() && !this->IsLoopPrePass())
5082
5168
{
5083
- this->currentBlock->globOptData.capturedArgs->ClearAll();
5084
5169
this->currentBlock->globOptData.changedSyms->ClearAll();
5085
5170
this->currentBlock->globOptData.capturedValues =
5086
5171
this->currentBlock->globOptData.capturedValuesCandidate;
@@ -6477,7 +6562,7 @@ GlobOpt::CopyPropReplaceOpnd(IR::Instr * instr, IR::Opnd * opnd, StackSym * copy
6477
6562
// We're creating a copy of this operand to be reused in the same spot in the flow, so we can copy all
6478
6563
// flow sensitive fields. However, we will do only a type check here (no property access) and only for
6479
6564
// the sake of downstream instructions, so the flags pertaining to this property access are irrelevant.
6480
- IR::PropertySymOpnd* checkObjTypeOpnd = propertySymOpnd->CopyForTypeCheckOnly( instr->m_func);
6565
+ IR::PropertySymOpnd* checkObjTypeOpnd = CreateOpndForTypeCheckOnly(propertySymOpnd, instr->m_func);
6481
6566
IR::Instr* checkObjTypeInstr = IR::Instr::New(Js::OpCode::CheckObjType, instr->m_func);
6482
6567
checkObjTypeInstr->SetSrc1(checkObjTypeOpnd);
6483
6568
checkObjTypeInstr->SetByteCodeOffset(instr);
@@ -7097,9 +7182,9 @@ GlobOpt::SetSymStoreDirect(ValueInfo * valueInfo, Sym * sym)
7097
7182
{
7098
7183
Sym * prevSymStore = valueInfo->GetSymStore();
7099
7184
if (prevSymStore && prevSymStore->IsStackSym() &&
7100
- prevSymStore->AsStackSym()->HasByteCodeRegSlot() &&
7101
- this->blockData.changedSyms)
7185
+ prevSymStore->AsStackSym()->HasByteCodeRegSlot())
7102
7186
{
7187
+ Assert(this->blockData.changedSyms != nullptr);
7103
7188
this->blockData.changedSyms->Set(prevSymStore->m_id);
7104
7189
}
7105
7190
valueInfo->SetSymStore(sym);
@@ -7122,8 +7207,9 @@ GlobOpt::SetValue(GlobOptBlockData *blockData, Value *val, Sym * sym)
7122
7207
else
7123
7208
{
7124
7209
SetValueToHashTable(blockData->symToValueMap, val, sym);
7125
- if (blockData->changedSyms && isStackSym && sym->AsStackSym()->HasByteCodeRegSlot())
7210
+ if (isStackSym && sym->AsStackSym()->HasByteCodeRegSlot())
7126
7211
{
7212
+ Assert(blockData->changedSyms != nullptr);
7127
7213
blockData->changedSyms->Set(sym->m_id);
7128
7214
}
7129
7215
}
@@ -21609,4 +21695,4 @@ ValueNumber JsUtil::ValueToKey<ValueNumber, Value *>::ToKey(Value *const &value)
21609
21695
{
21610
21696
Assert(value);
21611
21697
return value->GetValueNumber();
21612
- }
21698
+ }
0 commit comments