Skip to content

Commit ce04185

Browse files
committed
some write barrier fixes
- false poisitive on EntryPointInfo->jsMethod after native address reuse in recycler - false poisitive in arena allocator cacheBlockEnd reused in leaf block in recycler (sharing same page allocator) - overload ChangeToAssign in JIT code, check all posible assign for write barrier - missing barriers in various location
1 parent f3e5eaf commit ce04185

37 files changed

+184
-131
lines changed

lib/Backend/Lower.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -102,30 +102,30 @@ Lowerer::Lower()
102102
this->LowerRange(m_func->m_headInstr, m_func->m_tailInstr, defaultDoFastPath, loopFastPath);
103103

104104
#if DBG
105-
// TODO: (leish)(swb) implement for arm
105+
// TODO: (leish)(swb) implement for arm
106106
#if defined(_M_IX86) || defined(_M_AMD64)
107-
if (CONFIG_FLAG(ForceSoftwareWriteBarrier) && CONFIG_FLAG(RecyclerVerifyMark))
108-
{
109-
// find out all write barrier setting instr, call Recycler::WBSetBit for verification purpose
110-
// should do this in LowererMD::GenerateWriteBarrier, however, can't insert call instruction there
111-
FOREACH_INSTR_EDITING(instr, instrNext, m_func->m_headInstr)
112-
if (instr->m_src1 && instr->m_src1->IsAddrOpnd())
113-
{
114-
IR::AddrOpnd* addrOpnd = instr->m_src1->AsAddrOpnd();
115-
if (addrOpnd->GetAddrOpndKind() == IR::AddrOpndKindWriteBarrierCardTable)
116-
{
117-
auto& leaInstr = instr->m_prev->m_prev;
118-
auto& shrInstr = instr->m_prev;
119-
Assert(leaInstr->m_opcode == Js::OpCode::LEA);
120-
Assert(shrInstr->m_opcode == Js::OpCode::SHR);
121-
m_lowererMD.LoadHelperArgument(shrInstr, leaInstr->m_dst);
122-
IR::Instr* instrCall = IR::Instr::New(Js::OpCode::Call, m_func);
123-
shrInstr->InsertBefore(instrCall);
124-
m_lowererMD.ChangeToHelperCall(instrCall, IR::HelperWriteBarrierSetVerifyBit);
125-
}
126-
}
127-
NEXT_INSTR_EDITING
128-
}
107+
if (CONFIG_FLAG(ForceSoftwareWriteBarrier) && CONFIG_FLAG(RecyclerVerifyMark))
108+
{
109+
// find out all write barrier setting instr, call Recycler::WBSetBit for verification purpose
110+
// should do this in LowererMD::GenerateWriteBarrier, however, can't insert call instruction there
111+
FOREACH_INSTR_EDITING(instr, instrNext, m_func->m_headInstr)
112+
if (instr->m_src1 && instr->m_src1->IsAddrOpnd())
113+
{
114+
IR::AddrOpnd* addrOpnd = instr->m_src1->AsAddrOpnd();
115+
if (addrOpnd->GetAddrOpndKind() == IR::AddrOpndKindWriteBarrierCardTable)
116+
{
117+
auto& leaInstr = instr->m_prev->m_prev;
118+
auto& shrInstr = instr->m_prev;
119+
Assert(leaInstr->m_opcode == Js::OpCode::LEA);
120+
Assert(shrInstr->m_opcode == Js::OpCode::SHR);
121+
m_lowererMD.LoadHelperArgument(shrInstr, leaInstr->m_dst);
122+
IR::Instr* instrCall = IR::Instr::New(Js::OpCode::Call, m_func);
123+
shrInstr->InsertBefore(instrCall);
124+
m_lowererMD.ChangeToHelperCall(instrCall, IR::HelperWriteBarrierSetVerifyBit);
125+
}
126+
}
127+
NEXT_INSTR_EDITING
128+
}
129129
#endif
130130
#endif
131131

@@ -14558,7 +14558,7 @@ IR::Instr *Lowerer::InsertMove(IR::Opnd *dst, IR::Opnd *src, IR::Instr *const in
1455814558
}
1455914559
else
1456014560
{
14561-
LowererMD::ChangeToAssign(instr);
14561+
LowererMD::ChangeToAssignNoBarrierCheck(instr);
1456214562
}
1456314563

1456414564
return instr;

lib/Backend/LowerMDShared.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -756,11 +756,17 @@ IR::Instr* LowererMD::ChangeToHelperCallMem(IR::Instr * instr, IR::JnHelperMeth
756756
///----------------------------------------------------------------------------
757757

758758
IR::Instr *
759-
LowererMD::ChangeToAssign(IR::Instr * instr)
759+
LowererMD::ChangeToAssignNoBarrierCheck(IR::Instr * instr)
760760
{
761761
return ChangeToAssign(instr, instr->GetDst()->GetType());
762762
}
763763

764+
IR::Instr *
765+
LowererMD::ChangeToAssign(IR::Instr * instr)
766+
{
767+
return ChangeToWriteBarrierAssign(instr, instr->m_func);
768+
}
769+
764770
IR::Instr *
765771
LowererMD::ChangeToAssign(IR::Instr * instr, IRType type)
766772
{
@@ -4712,7 +4718,7 @@ LowererMD::GenerateLoadPolymorphicInlineCacheSlot(IR::Instr * instrLdSt, IR::Reg
47124718
instrLdSt->InsertBefore(instr);
47134719
}
47144720

4715-
void
4721+
IR::Instr *
47164722
LowererMD::ChangeToWriteBarrierAssign(IR::Instr * assignInstr, const Func* func)
47174723
{
47184724
#ifdef RECYCLER_WRITE_BARRIER_JIT
@@ -4747,17 +4753,19 @@ LowererMD::ChangeToWriteBarrierAssign(IR::Instr * assignInstr, const Func* func)
47474753
}
47484754
#endif
47494755

4750-
ChangeToAssign(assignInstr);
4756+
IR::Instr * instr = ChangeToAssignNoBarrierCheck(assignInstr);
47514757

47524758
// Now insert write barrier if necessary
47534759
#ifdef RECYCLER_WRITE_BARRIER_JIT
47544760
if (isPossibleBarrieredDest
47554761
&& assignInstr->m_opcode == Js::OpCode::MOV // ignore SSE instructions like MOVSD
47564762
&& assignInstr->GetSrc1()->IsWriteBarrierTriggerableValue())
47574763
{
4758-
LowererMD::GenerateWriteBarrier(assignInstr);
4764+
LowererMD::GenerateWriteBarrier(assignInstr);
47594765
}
47604766
#endif
4767+
4768+
return instr;
47614769
}
47624770

47634771
void

lib/Backend/LowerMDShared.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class LowererMD
8585
static IR::Instr * CreateAssign(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsertPt, bool generateWriteBarrier = true);
8686

8787
static IR::Instr * ChangeToAssign(IR::Instr * instr);
88+
static IR::Instr * ChangeToAssignNoBarrierCheck(IR::Instr * instr);
8889
static IR::Instr * ChangeToAssign(IR::Instr * instr, IRType type);
8990
static IR::Instr * ChangeToLea(IR::Instr *const instr, bool postRegAlloc = false);
9091
static void ImmedSrcToReg(IR::Instr * instr, IR::Opnd * newOpnd, int srcNum);
@@ -305,7 +306,7 @@ class LowererMD
305306

306307
void GenerateWriteBarrierAssign(IR::IndirOpnd * opndDst, IR::Opnd * opndSrc, IR::Instr * insertBeforeInstr);
307308
void GenerateWriteBarrierAssign(IR::MemRefOpnd * opndDst, IR::Opnd * opndSrc, IR::Instr * insertBeforeInstr);
308-
static void ChangeToWriteBarrierAssign(IR::Instr * assignInstr, const Func* func);
309+
static IR::Instr * ChangeToWriteBarrierAssign(IR::Instr * assignInstr, const Func* func);
309310

310311
static IR::BranchInstr * GenerateLocalInlineCacheCheck(IR::Instr * instrLdSt, IR::RegOpnd * opndType, IR::RegOpnd * opndInlineCache, IR::LabelInstr * labelNext, bool checkTypeWithoutProperty = false);
311312
static IR::BranchInstr * GenerateProtoInlineCacheCheck(IR::Instr * instrLdSt, IR::RegOpnd * opndType, IR::RegOpnd * opndInlineCache, IR::LabelInstr * labelNext);

lib/Backend/Sym.inl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ StackSym::IsArgSlotSym() const
8686
inline bool
8787
StackSym::IsParamSlotSym() const
8888
{
89-
return m_isParamSym;
89+
return m_isParamSym;
9090
}
9191

9292
///----------------------------------------------------------------------------

lib/Backend/SymTable.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,18 +246,18 @@ SymTable::GetArgSlotSym(Js::ArgSlot argSlotNum)
246246
StackSym *
247247
SymTable::GetImplicitParam(Js::ArgSlot paramSlotNum)
248248
{
249-
Assert(paramSlotNum - 1 < this->k_maxImplicitParamSlot);
249+
Assert(paramSlotNum - 1 < this->k_maxImplicitParamSlot);
250250

251-
if (this->m_implicitParams[paramSlotNum - 1])
252-
{
253-
return this->m_implicitParams[paramSlotNum - 1];
254-
}
255-
StackSym *implicitParamSym = StackSym::NewParamSlotSym(paramSlotNum, this->m_func, TyVar);
256-
implicitParamSym->m_isImplicitParamSym = true;
251+
if (this->m_implicitParams[paramSlotNum - 1])
252+
{
253+
return this->m_implicitParams[paramSlotNum - 1];
254+
}
255+
StackSym *implicitParamSym = StackSym::NewParamSlotSym(paramSlotNum, this->m_func, TyVar);
256+
implicitParamSym->m_isImplicitParamSym = true;
257257

258-
this->m_implicitParams[paramSlotNum - 1] = implicitParamSym;
258+
this->m_implicitParams[paramSlotNum - 1] = implicitParamSym;
259259

260-
return implicitParamSym;
260+
return implicitParamSym;
261261
}
262262

263263
///----------------------------------------------------------------------------

lib/Backend/SymTable.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,23 @@ class SymTable
1111
typedef JsUtil::BaseDictionary<Js::PropertyId, BVSparse<JitArenaAllocator> *, JitArenaAllocator, PowerOf2SizePolicy> PropertyEquivBvMap;
1212

1313
private:
14-
static const int k_symTableSize = 8192;
15-
static const int k_maxImplicitParamSlot = 4;
14+
static const int k_symTableSize = 8192;
15+
static const int k_maxImplicitParamSlot = 4;
1616
Sym * m_table[k_symTableSize];
17-
StackSym * m_implicitParams[k_maxImplicitParamSlot];
17+
StackSym * m_implicitParams[k_maxImplicitParamSlot];
1818
PropertyMap * m_propertyMap;
1919
Func * m_func;
2020
SymID m_currentID;
2121
SymID m_IDAdjustment;
2222

2323
public:
24-
PropertyEquivBvMap *m_propertyEquivBvMap;
24+
PropertyEquivBvMap *m_propertyEquivBvMap;
2525

2626
public:
2727
SymTable() : m_currentID(0), m_func(nullptr), m_IDAdjustment(0)
2828
{
29-
memset(m_table, 0, sizeof(m_table));
30-
memset(m_implicitParams, 0, sizeof(m_implicitParams));
29+
memset(m_table, 0, sizeof(m_table));
30+
memset(m_implicitParams, 0, sizeof(m_implicitParams));
3131
}
3232

3333

@@ -41,7 +41,7 @@ class SymTable
4141
void IncreaseStartingID(SymID IDIncrease);
4242
SymID NewID();
4343
StackSym * GetArgSlotSym(Js::ArgSlot argSlotNum);
44-
StackSym * GetImplicitParam(Js::ArgSlot paramSlotNum);
44+
StackSym * GetImplicitParam(Js::ArgSlot paramSlotNum);
4545
SymID GetMaxSymID() const;
4646
void ClearStackSymScratch();
4747
void SetIDAdjustment() { m_IDAdjustment = m_currentID;}

lib/Backend/amd64/LinearScanMD.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class LinearScanMD : public LinearScanMDShared
4444
public:
4545
static void SaveAllRegistersAndBailOut(BailOutRecord *const bailOutRecord);
4646
static void SaveAllRegistersAndBranchBailOut(BranchBailOutRecord *const bailOutRecord, const BOOL condition);
47-
static RegNum GetParamReg(IR::SymOpnd *symOpnd, Func *func);
47+
static RegNum GetParamReg(IR::SymOpnd *symOpnd, Func *func);
4848

4949
static uint GetRegisterSaveSlotCount() {
5050
return RegisterSaveSlotCount;

lib/Backend/arm/LinearScanMD.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class LinearScanMD : public LinearScanMDShared
4545
public:
4646
static void SaveAllRegistersAndBailOut(BailOutRecord *const bailOutRecord);
4747
static void SaveAllRegistersAndBranchBailOut(BranchBailOutRecord *const bailOutRecord, const BOOL condition);
48-
static RegNum GetParamReg(IR::SymOpnd *symOpnd, Func *func);
48+
static RegNum GetParamReg(IR::SymOpnd *symOpnd, Func *func);
4949

5050
bool IsAllocatable(RegNum reg, Func *func) const;
5151
static uint GetRegisterSaveSlotCount() {

lib/Backend/arm/LowerMD.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2343,11 +2343,17 @@ IR::Instr* LowererMD::ChangeToHelperCallMem(IR::Instr * instr, IR::JnHelperMeth
23432343
///----------------------------------------------------------------------------
23442344

23452345
IR::Instr *
2346-
LowererMD::ChangeToAssign(IR::Instr * instr)
2346+
LowererMD::ChangeToAssignNoBarrierCheck(IR::Instr * instr)
23472347
{
23482348
return ChangeToAssign(instr, instr->GetDst()->GetType());
23492349
}
23502350

2351+
IR::Instr *
2352+
LowererMD::ChangeToAssign(IR::Instr * instr)
2353+
{
2354+
return ChangeToWriteBarrierAssign(instr, instr->m_func);
2355+
}
2356+
23512357
IR::Instr *
23522358
LowererMD::ChangeToAssign(IR::Instr * instr, IRType type)
23532359
{
@@ -2381,13 +2387,13 @@ LowererMD::ChangeToAssign(IR::Instr * instr, IRType type)
23812387
return instr;
23822388
}
23832389

2384-
void
2390+
IR::Instr *
23852391
LowererMD::ChangeToWriteBarrierAssign(IR::Instr * assignInstr, const Func* func)
23862392
{
23872393
#ifdef RECYCLER_WRITE_BARRIER_JIT
23882394
// WriteBarrier-TODO- Implement ARM JIT
23892395
#endif
2390-
ChangeToAssign(assignInstr);
2396+
return ChangeToAssignNoBarrierCheck(assignInstr);
23912397
}
23922398

23932399
///----------------------------------------------------------------------------

lib/Backend/arm/LowerMD.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class LowererMD
7070
IR::Instr * ChangeToHelperCallMem(IR::Instr * instr, IR::JnHelperMethod helperMethod);
7171
static IR::Instr * CreateAssign(IR::Opnd *dst, IR::Opnd *src, IR::Instr *instrInsertPt, bool generateWriteBarrier = true);
7272
static IR::Instr * ChangeToAssign(IR::Instr * instr);
73+
static IR::Instr * ChangeToAssignNoBarrierCheck(IR::Instr * instr);
7374
static IR::Instr * ChangeToAssign(IR::Instr * instr, IRType type);
7475
static IR::Instr * ChangeToLea(IR::Instr *const instr, bool postRegAlloc = false);
7576
static IR::Instr * ForceDstToReg(IR::Instr *instr);
@@ -270,7 +271,7 @@ class LowererMD
270271
static void GenerateStFldFromLocalInlineCache(IR::Instr * instrStFld, IR::RegOpnd * opndBase, IR::Opnd * opndSrc, IR::RegOpnd * opndInlineCache, IR::LabelInstr * labelFallThru, bool isInlineSlot);
271272
void GenerateFunctionObjectTest(IR::Instr * callInstr, IR::RegOpnd *functionOpnd, bool isHelper, IR::LabelInstr* continueAfterExLabel = nullptr);
272273

273-
static void ChangeToWriteBarrierAssign(IR::Instr * assignInstr, const Func* func);
274+
static IR::Instr * ChangeToWriteBarrierAssign(IR::Instr * assignInstr, const Func* func);
274275

275276
int GetHelperArgsCount() { return this->helperCallArgsCount; }
276277
void ResetHelperArgsCount() { this->helperCallArgsCount = 0; }

0 commit comments

Comments
 (0)