Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Use ClassLayout in GenTreeObj/Blk
Browse files Browse the repository at this point in the history
  • Loading branch information
mikedn committed Apr 24, 2019
1 parent 3876a48 commit 4043b0f
Show file tree
Hide file tree
Showing 19 changed files with 152 additions and 293 deletions.
8 changes: 4 additions & 4 deletions src/jit/codegenarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)

// This GenTree node has data about GC pointers, this means we're dealing
// with CpObj.
assert(cpObjNode->gtGcPtrCount > 0);
assert(cpObjNode->GetLayout()->HasGCPtr());
#endif // DEBUG

// Consume the operands and get them into the right registers.
Expand All @@ -721,10 +721,10 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
instGen_MemoryBarrier();
}

unsigned slots = cpObjNode->gtSlots;
unsigned slots = cpObjNode->GetLayout()->GetSlotCount();
emitter* emit = getEmitter();

BYTE* gcPtrs = cpObjNode->gtGcPtrs;
const BYTE* gcPtrs = cpObjNode->GetLayout()->GetGCPtrs();

// If we can prove it's on the stack we don't need to use the write barrier.
emitAttr attr = EA_PTRSIZE;
Expand Down Expand Up @@ -753,7 +753,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
}
else
{
unsigned gcPtrCount = cpObjNode->gtGcPtrCount;
unsigned gcPtrCount = cpObjNode->GetLayout()->GetGCPtrCount();

unsigned i = 0;
while (i < slots)
Expand Down
8 changes: 4 additions & 4 deletions src/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2631,7 +2631,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)

// This GenTree node has data about GC pointers, this means we're dealing
// with CpObj.
assert(cpObjNode->gtGcPtrCount > 0);
assert(cpObjNode->GetLayout()->HasGCPtr());
#endif // DEBUG

// Consume the operands and get them into the right registers.
Expand All @@ -2640,7 +2640,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
gcInfo.gcMarkRegPtrVal(REG_WRITE_BARRIER_SRC_BYREF, srcAddrType);
gcInfo.gcMarkRegPtrVal(REG_WRITE_BARRIER_DST_BYREF, dstAddr->TypeGet());

unsigned slots = cpObjNode->gtSlots;
unsigned slots = cpObjNode->GetLayout()->GetSlotCount();

// Temp register(s) used to perform the sequence of loads and stores.
regNumber tmpReg = cpObjNode->ExtractTempReg();
Expand All @@ -2667,7 +2667,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)

emitter* emit = getEmitter();

BYTE* gcPtrs = cpObjNode->gtGcPtrs;
const BYTE* gcPtrs = cpObjNode->GetLayout()->GetGCPtrs();

// If we can prove it's on the stack we don't need to use the write barrier.
if (dstOnStack)
Expand Down Expand Up @@ -2699,7 +2699,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
}
else
{
unsigned gcPtrCount = cpObjNode->gtGcPtrCount;
unsigned gcPtrCount = cpObjNode->GetLayout()->GetGCPtrCount();

unsigned i = 0;
while (i < slots)
Expand Down
29 changes: 15 additions & 14 deletions src/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,8 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
// the xor ensures that only one of the two is setup, not both
assert((varNode != nullptr) ^ (addrNode != nullptr));

BYTE gcPtrArray[MAX_ARG_REG_COUNT] = {}; // TYPE_GC_NONE = 0
BYTE* gcPtrs = gcPtrArray;
BYTE gcPtrArray[MAX_ARG_REG_COUNT] = {}; // TYPE_GC_NONE = 0
const BYTE* gcPtrs = gcPtrArray;

unsigned gcPtrCount; // The count of GC pointers in the struct
unsigned structSize;
Expand All @@ -754,8 +754,8 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
isHfa = varDsc->lvIsHfa();
#ifdef _TARGET_ARM64_
gcPtrCount = varDsc->lvStructGcCount;
for (unsigned i = 0; i < gcPtrCount; ++i)
gcPtrs[i] = varDsc->lvGcLayout[i];
for (unsigned i = 0; i < gcPtrCount; ++i)
gcPtrArray[i] = varDsc->lvGcLayout[i];
#endif // _TARGET_ARM_
}
else // we must have a GT_OBJ
Expand All @@ -766,9 +766,9 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
// it provides (size and GC layout) even if the node wraps a lclvar. Due
// to struct reinterpretation (e.g. Unsafe.As<X, Y>) it is possible that
// the OBJ node has a different type than the lclvar.
CORINFO_CLASS_HANDLE objClass = source->gtObj.gtClass;
ClassLayout* layout = source->AsObj()->GetLayout();

structSize = compiler->info.compCompHnd->getClassSize(objClass);
structSize = layout->GetSize();

// The codegen code below doesn't have proper support for struct sizes
// that are not multiple of the slot size. Call arg morphing handles this
Expand All @@ -785,14 +785,15 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
assert((structSize % TARGET_POINTER_SIZE) == 0);
}

isHfa = compiler->IsHfa(objClass);
isHfa = compiler->IsHfa(layout->GetClassHandle());

#ifdef _TARGET_ARM64_
// On ARM32, Lowering places the correct GC layout information in the
// GenTreePutArgStk node and the code above already use that. On ARM64,
// this information is not available (in order to keep GenTreePutArgStk
// nodes small) and we need to retrieve it from the VM here.
gcPtrCount = compiler->info.compCompHnd->getClassGClayout(objClass, &gcPtrs[0]);
// nodes small) and we need to retrieve it from the OBJ node here.
gcPtrCount = layout->GetGCPtrCount();
gcPtrs = layout->GetGCPtrs();
#endif
}

Expand Down Expand Up @@ -1102,9 +1103,9 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
assert((varNode != nullptr) ^ (addrNode != nullptr));

// Setup the structSize, isHFa, and gcPtrCount
BYTE* gcPtrs = treeNode->gtGcPtrs;
unsigned gcPtrCount = treeNode->gtNumberReferenceSlots; // The count of GC pointers in the struct
int structSize = treeNode->getArgSize();
const BYTE* gcPtrs = treeNode->gtGcPtrs;
unsigned gcPtrCount = treeNode->gtNumberReferenceSlots; // The count of GC pointers in the struct
int structSize = treeNode->getArgSize();

// This is the varNum for our load operations,
// only used when we have a struct with a LclVar source
Expand Down Expand Up @@ -1140,7 +1141,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)
assert(baseReg != addrReg);

// We don't split HFA struct
assert(!compiler->IsHfa(source->gtObj.gtClass));
assert(!compiler->IsHfa(source->AsObj()->GetLayout()->GetClassHandle()));
}

// Put on stack first
Expand Down Expand Up @@ -3320,7 +3321,7 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* blkOp)

if (blkOp->OperIs(GT_STORE_OBJ) && blkOp->OperIsCopyBlkOp())
{
assert(blkOp->AsObj()->gtGcPtrCount != 0);
assert(blkOp->AsObj()->GetLayout()->HasGCPtr());
genCodeForCpObj(blkOp->AsObj());
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1091,8 +1091,8 @@ unsigned CodeGenInterface::InferStructOpSizeAlign(GenTree* op, unsigned* alignme

if (op->gtOper == GT_OBJ)
{
CORINFO_CLASS_HANDLE clsHnd = op->AsObj()->gtClass;
opSize = compiler->info.compCompHnd->getClassSize(clsHnd);
CORINFO_CLASS_HANDLE clsHnd = op->AsObj()->GetLayout()->GetClassHandle();
opSize = op->AsObj()->GetLayout()->GetSize();
alignment = roundUp(compiler->info.compCompHnd->getClassAlignmentRequirement(clsHnd), TARGET_POINTER_SIZE);
}
else if (op->gtOper == GT_LCL_VAR)
Expand Down
1 change: 0 additions & 1 deletion src/jit/codegenlinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,6 @@ void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
unsigned flags = splitArg->GetRegSpillFlagByIdx(i);
if ((flags & GTF_SPILLED) != 0)
{
BYTE* gcPtrs = splitArg->gtGcPtrs;
var_types dstType = splitArg->GetRegType(i);
regNumber dstReg = splitArg->GetRegNumByIdx(i);

Expand Down
18 changes: 9 additions & 9 deletions src/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2823,7 +2823,7 @@ void CodeGen::genCodeForStoreBlk(GenTreeBlk* storeBlkNode)

if (storeBlkNode->OperIs(GT_STORE_OBJ) && storeBlkNode->OperIsCopyBlkOp() && !storeBlkNode->gtBlkOpGcUnsafe)
{
assert(storeBlkNode->AsObj()->gtGcPtrCount != 0);
assert(storeBlkNode->AsObj()->GetLayout()->HasGCPtr());
genCodeForCpObj(storeBlkNode->AsObj());
return;
}
Expand Down Expand Up @@ -3618,7 +3618,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)

// If the GenTree node has data about GC pointers, this means we're dealing
// with CpObj, so this requires special logic.
assert(cpObjNode->gtGcPtrCount > 0);
assert(cpObjNode->GetLayout()->HasGCPtr());

// MovSp (alias for movsq on x64 and movsd on x86) instruction is used for copying non-gcref fields
// and it needs src = RSI and dst = RDI.
Expand Down Expand Up @@ -3656,7 +3656,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
gcInfo.gcMarkRegPtrVal(REG_RSI, srcAddrType);
gcInfo.gcMarkRegPtrVal(REG_RDI, dstAddr->TypeGet());

unsigned slots = cpObjNode->gtSlots;
unsigned slots = cpObjNode->GetLayout()->GetSlotCount();

// If we can prove it's on the stack we don't need to use the write barrier.
if (dstOnStack)
Expand All @@ -3683,8 +3683,8 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
}
else
{
BYTE* gcPtrs = cpObjNode->gtGcPtrs;
unsigned gcPtrCount = cpObjNode->gtGcPtrCount;
const BYTE* gcPtrs = cpObjNode->GetLayout()->GetGCPtrs();
unsigned gcPtrCount = cpObjNode->GetLayout()->GetGCPtrCount();

unsigned i = 0;
while (i < slots)
Expand Down Expand Up @@ -5417,12 +5417,12 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
if (source->TypeGet() == TYP_STRUCT)
{
GenTreeObj* obj = source->AsObj();
unsigned argBytes = roundUp(obj->gtBlkSize, TARGET_POINTER_SIZE);
unsigned argBytes = roundUp(obj->GetLayout()->GetSize(), TARGET_POINTER_SIZE);
#ifdef _TARGET_X86_
// If we have an OBJ, we must have created a copy if the original arg was not a
// local and was not a multiple of TARGET_POINTER_SIZE.
// Note that on x64/ux this will be handled by unrolling in genStructPutArgUnroll.
assert((argBytes == obj->gtBlkSize) || obj->Addr()->IsLocalAddrExpr());
assert((argBytes == obj->GetLayout()->GetSize()) || obj->Addr()->IsLocalAddrExpr());
#endif // _TARGET_X86_
assert((curArgTabEntry->numSlots * TARGET_POINTER_SIZE) == argBytes);
}
Expand Down Expand Up @@ -8197,7 +8197,7 @@ void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk)
assert(m_pushStkArg);

GenTree* srcAddr = source->gtGetOp1();
BYTE* gcPtrs = putArgStk->gtGcPtrs;
const BYTE* gcPtrs = putArgStk->gtGcPtrs;
const unsigned numSlots = putArgStk->gtNumSlots;

regNumber srcRegNum = srcAddr->gtRegNum;
Expand Down Expand Up @@ -8261,7 +8261,7 @@ void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk)
unsigned numGCSlotsCopied = 0;
#endif // DEBUG

BYTE* gcPtrs = putArgStk->gtGcPtrs;
const BYTE* gcPtrs = putArgStk->gtGcPtrs;
const unsigned numSlots = putArgStk->gtNumSlots;
for (unsigned i = 0; i < numSlots;)
{
Expand Down
2 changes: 1 addition & 1 deletion src/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9286,7 +9286,7 @@ int cTreeFlagsIR(Compiler* comp, GenTree* tree)

case GT_OBJ:
case GT_STORE_OBJ:
if (tree->AsObj()->HasGCPtr())
if (tree->AsObj()->GetLayout()->HasGCPtr())
{
chars += printf("[BLK_HASGCPTR]");
}
Expand Down
Loading

0 comments on commit 4043b0f

Please sign in to comment.