Skip to content

Commit

Permalink
Merge pull request dotnet#7013 from swaroop-sridhar/PtrStruct
Browse files Browse the repository at this point in the history
GcInfo: Report Struct containing one GcPointer correctly
  • Loading branch information
swaroop-sridhar authored Sep 1, 2016
2 parents 3961806 + 060e0c6 commit 68afd5c
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,7 +906,7 @@ var_types Compiler::getArgTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
// that multiple registers are used to return this struct.
//
var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
structPassingKind* wbReturnStruct,
structPassingKind* wbReturnStruct /* = nullptr */,
unsigned structSize /* = 0 */)
{
var_types useType = TYP_UNKNOWN;
Expand Down
2 changes: 1 addition & 1 deletion src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -3841,7 +3841,7 @@ class Compiler
// If you have already retrieved the struct size then pass it as the optional third argument
//
var_types getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
structPassingKind* wbPassStruct,
structPassingKind* wbPassStruct = nullptr,
unsigned structSize = 0);

#ifdef DEBUG
Expand Down
42 changes: 33 additions & 9 deletions src/jit/gcencode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3541,6 +3541,7 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz
switch (compiler->info.compRetType)
{
case TYP_REF:
case TYP_ARRAY:
returnKind = RT_Object;
break;
case TYP_BYREF:
Expand All @@ -3549,19 +3550,42 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz
case TYP_STRUCT:
{
CORINFO_CLASS_HANDLE structType = compiler->info.compMethodInfo->args.retTypeClass;
if (compiler->IsMultiRegReturnedType(structType) && !compiler->IsHfa(structType))
var_types retType = compiler->getReturnTypeForStruct(structType);

switch (retType)
{
BYTE gcPtrs[2] = {TYPE_GC_NONE, TYPE_GC_NONE};
compiler->info.compCompHnd->getClassGClayout(structType, gcPtrs);
case TYP_ARRAY:
_ASSERTE(false && "TYP_ARRAY unexpected from getReturnTypeForStruct()");

ReturnKind first = GCTypeToReturnKind((CorInfoGCType)gcPtrs[0]);
ReturnKind second = GCTypeToReturnKind((CorInfoGCType)gcPtrs[1]);
case TYP_REF:
returnKind = RT_Object;
break;

returnKind = GetStructReturnKind(first, second);
}
else
{
case TYP_BYREF:
returnKind = RT_ByRef;
break;

case TYP_STRUCT:
if (compiler->IsHfa(structType))
{
returnKind = RT_Scalar;
}
else
{
// Multi-reg return
BYTE gcPtrs[2] = { TYPE_GC_NONE, TYPE_GC_NONE };
compiler->info.compCompHnd->getClassGClayout(structType, gcPtrs);

ReturnKind first = GCTypeToReturnKind((CorInfoGCType)gcPtrs[0]);
ReturnKind second = GCTypeToReturnKind((CorInfoGCType)gcPtrs[1]);

returnKind = GetStructReturnKind(first, second);
}
break;

default:
returnKind = RT_Scalar;
break;
}
break;
}
Expand Down

0 comments on commit 68afd5c

Please sign in to comment.