Skip to content

Commit

Permalink
[LoongArch64] Fix the ArgIteratorTemplate::GetNextOffset() return a…
Browse files Browse the repository at this point in the history
…rgOfs for 'ELEMENT_TYPE_VALUETYPE' which is flattened liking struct{Arr[], float}. (#103108)

* [LoongArch64] Fix the `ArgIteratorTemplate::GetNextOffset()` return argOfs for 'ELEMENT_TYPE_VALUETYPE' which is flattened liking struct{Arr[], float}.
* The 'ELEMENT_TYPE_VALUETYPE' is marked to 'TYPE_GC_OTHER' and the first flattened element Arr[] should GC.
* This also fixed the assert failure "!CREATE_CHECK_STRING(pMT && pMT->Validate())" under GC=8 of MarshalStructAsLayoutSeq.sh.

* Update callingconvention.h

delete redundancy condition.
  • Loading branch information
LuckyXu-HF authored Jun 6, 2024
1 parent 035ce10 commit 6575440
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,16 @@ public int GetNextOffset()
_hasArgLocDescForStructInRegs = true;
_argLocDescForStructInRegs.m_floatFlags = floatFieldFlags;

int argOfsInner = _transitionBlock.OffsetOfFloatArgumentRegisters + _loongarch64IdxFPReg * 8;
int argOfsInner = 0;
if ((floatFieldFlags & (uint)StructFloatFieldInfoFlags.STRUCT_FLOAT_FIELD_SECOND) != 0)
{
argOfsInner = _transitionBlock.OffsetOfArgumentRegisters + _loongarch64IdxGenReg * 8;
}
else
{
argOfsInner = _transitionBlock.OffsetOfFloatArgumentRegisters + _loongarch64IdxFPReg * 8;
}

_loongarch64IdxFPReg++;
_loongarch64IdxGenReg++;
return argOfsInner;
Expand Down
23 changes: 18 additions & 5 deletions src/coreclr/vm/callingconvention.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@ struct TransitionBlock
{
return argLocDescForStructInRegs->m_cFloatReg > 0;
}
#elif defined(TARGET_LOONGARCH64)
if (argLocDescForStructInRegs != NULL)
{
return argLocDescForStructInRegs->m_cFloatReg > 0;
}
#endif
return offset < 0;
}
Expand Down Expand Up @@ -1719,16 +1724,24 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()

if ((1 + m_idxFPReg <= NUM_ARGUMENT_REGISTERS) && (m_idxGenReg + 1 <= NUM_ARGUMENT_REGISTERS))
{
int argOfs = 0;
m_argLocDescForStructInRegs.Init();
m_argLocDescForStructInRegs.m_idxFloatReg = m_idxFPReg;
m_argLocDescForStructInRegs.m_cFloatReg = 1;
int argOfs = TransitionBlock::GetOffsetOfFloatArgumentRegisters() + m_idxFPReg * 8;
m_idxFPReg += 1;

m_argLocDescForStructInRegs.m_structFields = flags;

m_argLocDescForStructInRegs.m_idxGenReg = m_idxGenReg;
m_argLocDescForStructInRegs.m_cGenReg = 1;
m_argLocDescForStructInRegs.m_structFields = flags;

if (flags & STRUCT_FLOAT_FIELD_SECOND)
{
argOfs = TransitionBlock::GetOffsetOfArgumentRegisters() + m_idxGenReg * 8;
}
else
{
argOfs = TransitionBlock::GetOffsetOfFloatArgumentRegisters() + m_idxFPReg * 8;
}

m_idxFPReg += 1;
m_idxGenReg += 1;

m_hasArgLocDescForStructInRegs = true;
Expand Down
21 changes: 21 additions & 0 deletions src/coreclr/vm/loongarch64/profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,27 @@ LPVOID ProfileArgIterator::GetNextArgAddr()
if (TransitionBlock::IsArgumentRegisterOffset(argOffset))
{
pArg = (LPBYTE)&pData->argumentRegisters + (argOffset - TransitionBlock::GetOffsetOfArgumentRegisters());
ArgLocDesc* pArgLocDesc = m_argIterator.GetArgLocDescForStructInRegs();

if (pArgLocDesc)
{
if (pArgLocDesc->m_cFloatReg == 1)
{
_ASSERTE(!(pArgLocDesc->m_structFields & STRUCT_FLOAT_FIELD_FIRST));
_ASSERTE(pArgLocDesc->m_structFields & STRUCT_FLOAT_FIELD_SECOND);

UINT32 bufferPos = m_bufferPos;
UINT64* dst = (UINT64*)&pData->buffer[bufferPos];
m_bufferPos += 16;

*dst = *(UINT64*)pArg;
*(double*)(dst + 1) = pData->floatArgumentRegisters.f[pArgLocDesc->m_idxFloatReg];

return (LPBYTE)&pData->buffer[bufferPos];
}

_ASSERTE(pArgLocDesc->m_cFloatReg == 0);
}
}
else
{
Expand Down

0 comments on commit 6575440

Please sign in to comment.