Skip to content

Commit 0298d2e

Browse files
committed
Migrate some string/array ctor smarts from interpexec to compiler
1 parent b040e0d commit 0298d2e

File tree

2 files changed

+34
-20
lines changed

2 files changed

+34
-20
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3007,36 +3007,53 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
30073007
m_compHnd->getMethodSig(ctorMethod, &ctorSignature);
30083008
ctorClass = m_compHnd->getMethodClass(ctorMethod);
30093009
int32_t numArgs = ctorSignature.numArgs;
3010+
bool isStringOrArray = m_compHnd->getClassAttribs(ctorClass) & CORINFO_FLG_VAROBJSIZE;
3011+
int32_t numExtraArgs = isStringOrArray ? 1 : 2;
3012+
int32_t callArgOffset = isStringOrArray ? 0 : 1;
30103013

3011-
// TODO Special case array ctor / string ctor
30123014
m_pStackPointer -= numArgs;
30133015

30143016
// Allocate callArgs for the call, this + numArgs + terminator
3015-
int32_t *callArgs = (int32_t*) AllocMemPool((numArgs + 2) * sizeof(int32_t));
3017+
int32_t *callArgs = (int32_t*) AllocMemPool((numArgs + numExtraArgs) * sizeof(int32_t));
30163018
for (int i = 0; i < numArgs; i++)
3017-
callArgs[i + 1] = m_pStackPointer[i].var;
3018-
callArgs[numArgs + 1] = -1;
3019+
callArgs[i + callArgOffset] = m_pStackPointer[i].var;
3020+
callArgs[numArgs + callArgOffset] = -1;
30193021

30203022
// Push the return value and `this` argument to the ctor
30213023
InterpType retType = GetInterpType(m_compHnd->asCorInfoType(ctorClass));
3022-
int32_t vtsize = 0;
3023-
if (retType == InterpTypeVT)
3024+
int32_t vtsize = 0, dVar, thisVar;
3025+
if (isStringOrArray)
3026+
{
3027+
// result
3028+
PushInterpType(retType, ctorClass);
3029+
dVar = m_pStackPointer[-1].var;
3030+
thisVar = -1;
3031+
}
3032+
else if (retType == InterpTypeVT)
30243033
{
30253034
vtsize = m_compHnd->getClassSize(ctorClass);
30263035
PushTypeVT(ctorClass, vtsize);
30273036
PushInterpType(InterpTypeByRef, NULL);
3037+
dVar = m_pStackPointer[-2].var;
3038+
thisVar = m_pStackPointer[-1].var;
30283039
}
30293040
else
30303041
{
3042+
// result
30313043
PushInterpType(retType, ctorClass);
3044+
// this-ref
30323045
PushInterpType(retType, ctorClass);
3046+
dVar = m_pStackPointer[-2].var;
3047+
thisVar = m_pStackPointer[-1].var;
3048+
}
3049+
3050+
if (!isStringOrArray)
3051+
{
3052+
// Consider this arg as being defined, although newobj defines it
3053+
AddIns(INTOP_DEF);
3054+
m_pLastNewIns->SetDVar(thisVar);
3055+
callArgs[0] = thisVar;
30333056
}
3034-
int32_t dVar = m_pStackPointer[-2].var;
3035-
int32_t thisVar = m_pStackPointer[-1].var;
3036-
// Consider this arg as being defined, although newobj defines it
3037-
AddIns(INTOP_DEF);
3038-
m_pLastNewIns->SetDVar(thisVar);
3039-
callArgs[0] = thisVar;
30403057

30413058
if (retType == InterpTypeVT)
30423059
{
@@ -3048,6 +3065,7 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
30483065
AddIns(INTOP_NEWOBJ);
30493066
m_pLastNewIns->data[1] = GetDataItemIndex(ctorClass);
30503067
}
3068+
30513069
m_pLastNewIns->data[0] = GetMethodDataItemIndex(ctorMethod);
30523070
m_pLastNewIns->SetSVar(CALL_ARGS_SVAR);
30533071
m_pLastNewIns->SetDVar(dVar);
@@ -3057,7 +3075,8 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo)
30573075
m_pLastNewIns->info.pCallInfo->pCallArgs = callArgs;
30583076

30593077
// Pop this, the result of the newobj still remains on the stack
3060-
m_pStackPointer--;
3078+
if (!isStringOrArray)
3079+
m_pStackPointer--;
30613080
break;
30623081
}
30633082
case CEE_DUP:

src/coreclr/vm/interpexec.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,17 +1199,12 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr
11991199
// fcall that is basically a static method that returns the new instance.
12001200
if (pMD && pClass->HasComponentSize())
12011201
{
1202-
// The compiler didn't know about this so it reserved space for a this-reference. We need to skip
1203-
// past that reserved space, since the callee doesn't expect it.
1204-
LOCAL_VAR(callArgsOffset, void*) = nullptr; // and zero it too! it might get scanned by the GC.
1205-
callArgsOffset += sizeof(StackVal);
1206-
12071202
// Get the address of the fcall that implements the ctor
12081203
PCODE code = pMD->TryGetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY);
12091204
assert(code);
12101205

1211-
// callArgsOffset now only points to the ctor arguments, which are what the fcall expects.
1212-
// returnOffset still points to where the new instance goes, and the fcall will write it there.
1206+
// callArgsOffset points to the ctor arguments, which are what the fcall expects.
1207+
// returnOffset points to where the new instance goes, and the fcall will write it there.
12131208
InvokeCompiledMethod(pMD, stack + callArgsOffset, stack + returnOffset, code);
12141209
ip += 5;
12151210
break;

0 commit comments

Comments
 (0)