From 28c91be1e04702d98e09346a86881912d92f38b9 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 16 May 2025 08:55:28 -0700 Subject: [PATCH 1/6] [WIP] Implement ldtoken in the interpreter Add a 'self' value to the InterpMethod header so we can detect invalid InterpMethod pointers early instead of crashing downstream Cleanup, expand test Repair merge damage --- src/coreclr/interpreter/compiler.cpp | 36 +++++++++++++++++++++ src/coreclr/interpreter/interpretershared.h | 2 ++ src/coreclr/interpreter/intops.def | 2 ++ src/coreclr/vm/interpexec.cpp | 19 +++++++++++ src/tests/JIT/interpreter/Interpreter.cs | 28 ++++++++++++++++ 5 files changed, 87 insertions(+) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index b2ea69924dbdc6..2bc877de9e7513 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -3710,6 +3710,42 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) break; } + case CEE_LDTOKEN: + { + AddIns(INTOP_LDTOKEN); + + CORINFO_RESOLVED_TOKEN resolvedToken = { 0 }; + resolvedToken.tokenScope = m_compScopeHnd; + resolvedToken.tokenContext = METHOD_BEING_COMPILED_CONTEXT(); + resolvedToken.token = getU4LittleEndian(m_ip + 1); + resolvedToken.tokenType = CORINFO_TOKENKIND_Ldtoken; + m_compHnd->resolveToken(&resolvedToken); + + CORINFO_CLASS_HANDLE clsHnd = m_compHnd->getTokenTypeAsHandle(&resolvedToken); + PushStackType(StackTypeVT, clsHnd); + m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); + + // see jit/importer.cpp CEE_LDTOKEN + CorInfoHelpFunc helper; + if (resolvedToken.hClass) { + helper = CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE; + m_pLastNewIns->data[0] = GetDataItemIndex(resolvedToken.hClass); + } else if (resolvedToken.hMethod) { + helper = CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD; + m_pLastNewIns->data[0] = GetDataItemIndex(resolvedToken.hMethod); + } else if (resolvedToken.hField) { + helper = CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD; + m_pLastNewIns->data[0] = GetDataItemIndex(resolvedToken.hField); + } else { + helper = CORINFO_HELP_FAIL_FAST; + assert(!"Token not resolved or resolved to unexpected type"); + } + + m_pLastNewIns->data[1] = GetDataItemIndexForHelperFtn(helper); + m_ip += 5; + break; + } + default: assert(0); break; diff --git a/src/coreclr/interpreter/interpretershared.h b/src/coreclr/interpreter/interpretershared.h index f4a93666f2906c..13d8bfdacfbe78 100644 --- a/src/coreclr/interpreter/interpretershared.h +++ b/src/coreclr/interpreter/interpretershared.h @@ -16,6 +16,7 @@ struct InterpMethod { + InterpMethod *self; CORINFO_METHOD_HANDLE methodHnd; int32_t allocaSize; void** pDataItems; @@ -23,6 +24,7 @@ struct InterpMethod InterpMethod(CORINFO_METHOD_HANDLE methodHnd, int32_t allocaSize, void** pDataItems, bool initLocals) { + this->self = this; this->methodHnd = methodHnd; this->allocaSize = allocaSize; this->pDataItems = pDataItems; diff --git a/src/coreclr/interpreter/intops.def b/src/coreclr/interpreter/intops.def index 15cbdb336d8998..8f1a45f8611ae0 100644 --- a/src/coreclr/interpreter/intops.def +++ b/src/coreclr/interpreter/intops.def @@ -42,6 +42,8 @@ OPDEF(INTOP_STELEM_I8, "stelem.i8", 4, 0, 3, InterpOpNoArgs) OPDEF(INTOP_STELEM_R4, "stelem.r4", 4, 0, 3, InterpOpNoArgs) OPDEF(INTOP_STELEM_R8, "stelem.r8", 4, 0, 3, InterpOpNoArgs) +OPDEF(INTOP_LDTOKEN, "ldtoken", 4, 1, 0, InterpOpTwoInts) // [token data item] [conversion helper func] + OPDEF(INTOP_MOV_I4_I1, "mov.i4.i1", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_MOV_I4_U1, "mov.i4.u1", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_MOV_I4_I2, "mov.i4.i2", 3, 1, 1, InterpOpNoArgs) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 0bfbe460275879..22a6a7c6adf896 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -91,6 +91,8 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr int8_t *stack; InterpMethod *pMethod = *(InterpMethod**)pFrame->startIp; + assert(pMethod->self == pMethod); + pThreadContext->pStackPointer = pFrame->pStack + pMethod->allocaSize; ip = pFrame->startIp + sizeof(InterpMethod*) / sizeof(int32_t); stack = pFrame->pStack; @@ -1172,6 +1174,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr // Set execution state for the new frame pMethod = *(InterpMethod**)pFrame->startIp; + assert(pMethod->self == pMethod); stack = pFrame->pStack; ip = pFrame->startIp + sizeof(InterpMethod*) / sizeof(int32_t); pThreadContext->pStackPointer = stack + pMethod->allocaSize; @@ -1421,6 +1424,20 @@ do { \ case INTOP_STELEM_R8: { STELEM(double, double); + } + case INTOP_LDTOKEN: + { + int dreg = ip[1]; + void *nativeHandle = pMethod->pDataItems[ip[2]]; + size_t helperDirectOrIndirect = (size_t)pMethod->pDataItems[ip[3]]; + HELPER_FTN_PP helper = nullptr; + if (helperDirectOrIndirect & INTERP_INDIRECT_HELPER_TAG) + helper = *(HELPER_FTN_PP *)(helperDirectOrIndirect & ~INTERP_INDIRECT_HELPER_TAG); + else + helper = (HELPER_FTN_PP)helperDirectOrIndirect; + void *managedHandle = helper(nativeHandle); + LOCAL_VAR(dreg, void*) = managedHandle; + ip += 4; break; } case INTOP_FAILFAST: @@ -1456,6 +1473,7 @@ do { \ stack = pFrame->pStack; pMethod = *(InterpMethod**)pFrame->startIp; + assert(pMethod->self == pMethod); pThreadContext->pStackPointer = pFrame->pStack + pMethod->allocaSize; goto MAIN_LOOP; } @@ -1472,6 +1490,7 @@ do { \ ip = pFrame->ip; stack = pFrame->pStack; pMethod = *(InterpMethod**)pFrame->startIp; + assert(pMethod->self == pMethod); pFrame->ip = NULL; pThreadContext->pStackPointer = pFrame->pStack + pMethod->allocaSize; diff --git a/src/tests/JIT/interpreter/Interpreter.cs b/src/tests/JIT/interpreter/Interpreter.cs index 866102e9f2e480..dce3a89f32d075 100644 --- a/src/tests/JIT/interpreter/Interpreter.cs +++ b/src/tests/JIT/interpreter/Interpreter.cs @@ -419,6 +419,13 @@ public static void RunInterpreterTests() if (!TestSizeof()) Environment.FailFast(null); + if (!TestLdtoken()) + Environment.FailFast(null); + /* + if (!TestMdArray()) + Environment.FailFast(null); + */ + System.GC.Collect(); } @@ -959,4 +966,25 @@ public static unsafe bool TestSizeof() return false; return true; } + + public static bool TestLdtoken() + { + Type t = typeof(int); + int i = 42; + if (!ReferenceEquals(t, i.GetType())) + return false; + // FIXME: Find a way to get roslyn to generate ldtoken for fields and methods, then test those here + return true; + } + + public static bool TestMdArray() + { + // FIXME: This generates roughly: + // newobj int[,].ctor + // ldtoken int[,] + // call System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray + // The newobj currently fails because int[,].ctor isn't a real method, the interp needs to use getCallInfo to determine how to invoke it + int[,] a = {{1, 2}, {3, 4}}; + return a[0, 1] == 2; + } } From 9d7bc28bb122d923829490a99a1079c28b50b943 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 20 May 2025 07:45:09 -0700 Subject: [PATCH 2/6] Repair merge damage --- src/coreclr/vm/interpexec.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 22a6a7c6adf896..0d838138dd3d7b 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -1424,6 +1424,7 @@ do { \ case INTOP_STELEM_R8: { STELEM(double, double); + break; } case INTOP_LDTOKEN: { From 0ab8272e9802858e7599b9e40713f704744e54fe Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 20 May 2025 08:05:05 -0700 Subject: [PATCH 3/6] Assert when failing to get a helper ftn Add commented out test for ldtoken on fields and methods --- src/coreclr/interpreter/compiler.cpp | 1 + src/tests/JIT/interpreter/Interpreter.cs | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 2bc877de9e7513..8a98c10276d0c8 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -1736,6 +1736,7 @@ int32_t InterpCompiler::GetDataItemIndexForHelperFtn(CorInfoHelpFunc ftn) size_t data = !direct ? (size_t)indirect | INTERP_INDIRECT_HELPER_TAG : (size_t)direct; + assert(data); return GetDataItemIndex((void*)data); } diff --git a/src/tests/JIT/interpreter/Interpreter.cs b/src/tests/JIT/interpreter/Interpreter.cs index dce3a89f32d075..a78df5ef49b14e 100644 --- a/src/tests/JIT/interpreter/Interpreter.cs +++ b/src/tests/JIT/interpreter/Interpreter.cs @@ -967,13 +967,19 @@ public static unsafe bool TestSizeof() return true; } + public static int LdtokenField = 7; + public static bool TestLdtoken() { Type t = typeof(int); int i = 42; if (!ReferenceEquals(t, i.GetType())) return false; - // FIXME: Find a way to get roslyn to generate ldtoken for fields and methods, then test those here + // These generate field and method ldtoken opcodes, but the test fails because we are missing castclass and possibly also generics + /* + System.Linq.Expressions.Expression> f = () => LdtokenField; + System.Linq.Expressions.Expression a = () => TestLdtoken(); + */ return true; } From cb9d957496192438fbbf03ce8a0db043e43d1204 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 21 May 2025 08:04:05 -0700 Subject: [PATCH 4/6] Address PR feedback --- src/coreclr/interpreter/compiler.cpp | 6 +----- src/coreclr/interpreter/interpretershared.h | 13 +++++++++++++ src/coreclr/vm/interpexec.cpp | 8 ++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 8a98c10276d0c8..4113e279402472 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -3716,11 +3716,7 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) AddIns(INTOP_LDTOKEN); CORINFO_RESOLVED_TOKEN resolvedToken = { 0 }; - resolvedToken.tokenScope = m_compScopeHnd; - resolvedToken.tokenContext = METHOD_BEING_COMPILED_CONTEXT(); - resolvedToken.token = getU4LittleEndian(m_ip + 1); - resolvedToken.tokenType = CORINFO_TOKENKIND_Ldtoken; - m_compHnd->resolveToken(&resolvedToken); + ResolveToken(getU4LittleEndian(m_ip + 1), CORINFO_TOKENKIND_Ldtoken, &resolvedToken); CORINFO_CLASS_HANDLE clsHnd = m_compHnd->getTokenTypeAsHandle(&resolvedToken); PushStackType(StackTypeVT, clsHnd); diff --git a/src/coreclr/interpreter/interpretershared.h b/src/coreclr/interpreter/interpretershared.h index 13d8bfdacfbe78..14b25f71c2c82f 100644 --- a/src/coreclr/interpreter/interpretershared.h +++ b/src/coreclr/interpreter/interpretershared.h @@ -16,7 +16,9 @@ struct InterpMethod { +#if DEBUG InterpMethod *self; +#endif CORINFO_METHOD_HANDLE methodHnd; int32_t allocaSize; void** pDataItems; @@ -24,12 +26,23 @@ struct InterpMethod InterpMethod(CORINFO_METHOD_HANDLE methodHnd, int32_t allocaSize, void** pDataItems, bool initLocals) { +#if DEBUG this->self = this; +#endif this->methodHnd = methodHnd; this->allocaSize = allocaSize; this->pDataItems = pDataItems; this->initLocals = initLocals; } + + bool CheckIntegrity() + { +#if DEBUG + return this->self == this; +#else + return true; +#endif + } }; #endif diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 0d838138dd3d7b..15d91a4cf5398c 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -91,7 +91,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr int8_t *stack; InterpMethod *pMethod = *(InterpMethod**)pFrame->startIp; - assert(pMethod->self == pMethod); + assert(pMethod->CheckIntegrity()); pThreadContext->pStackPointer = pFrame->pStack + pMethod->allocaSize; ip = pFrame->startIp + sizeof(InterpMethod*) / sizeof(int32_t); @@ -1174,7 +1174,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr // Set execution state for the new frame pMethod = *(InterpMethod**)pFrame->startIp; - assert(pMethod->self == pMethod); + assert(pMethod->CheckIntegrity()); stack = pFrame->pStack; ip = pFrame->startIp + sizeof(InterpMethod*) / sizeof(int32_t); pThreadContext->pStackPointer = stack + pMethod->allocaSize; @@ -1474,7 +1474,7 @@ do { \ stack = pFrame->pStack; pMethod = *(InterpMethod**)pFrame->startIp; - assert(pMethod->self == pMethod); + assert(pMethod->CheckIntegrity()); pThreadContext->pStackPointer = pFrame->pStack + pMethod->allocaSize; goto MAIN_LOOP; } @@ -1491,7 +1491,7 @@ do { \ ip = pFrame->ip; stack = pFrame->pStack; pMethod = *(InterpMethod**)pFrame->startIp; - assert(pMethod->self == pMethod); + assert(pMethod->CheckIntegrity()); pFrame->ip = NULL; pThreadContext->pStackPointer = pFrame->pStack + pMethod->allocaSize; From 51fec19d12d2f6b1ae95b392c7d7b0bc39821e01 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 21 May 2025 08:16:58 -0700 Subject: [PATCH 5/6] Address PR feedback --- src/coreclr/interpreter/compiler.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 4113e279402472..9b3a3a809a26f8 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -3715,7 +3715,7 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) { AddIns(INTOP_LDTOKEN); - CORINFO_RESOLVED_TOKEN resolvedToken = { 0 }; + CORINFO_RESOLVED_TOKEN resolvedToken; ResolveToken(getU4LittleEndian(m_ip + 1), CORINFO_TOKENKIND_Ldtoken, &resolvedToken); CORINFO_CLASS_HANDLE clsHnd = m_compHnd->getTokenTypeAsHandle(&resolvedToken); @@ -3724,16 +3724,23 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) // see jit/importer.cpp CEE_LDTOKEN CorInfoHelpFunc helper; - if (resolvedToken.hClass) { + if (resolvedToken.hClass) + { helper = CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE; m_pLastNewIns->data[0] = GetDataItemIndex(resolvedToken.hClass); - } else if (resolvedToken.hMethod) { + } + else if (resolvedToken.hMethod) + { helper = CORINFO_HELP_METHODDESC_TO_STUBRUNTIMEMETHOD; m_pLastNewIns->data[0] = GetDataItemIndex(resolvedToken.hMethod); - } else if (resolvedToken.hField) { + } + else if (resolvedToken.hField) + { helper = CORINFO_HELP_FIELDDESC_TO_STUBRUNTIMEFIELD; m_pLastNewIns->data[0] = GetDataItemIndex(resolvedToken.hField); - } else { + } + else + { helper = CORINFO_HELP_FAIL_FAST; assert(!"Token not resolved or resolved to unexpected type"); } From 3094ac08e3d000241d2af39858cf321b11f45dd5 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Wed, 21 May 2025 13:44:52 -0700 Subject: [PATCH 6/6] Fix CallStubGenerator ignoring certain systemv classifications on linux/mac --- src/coreclr/vm/callstubgenerator.cpp | 80 ++++++++++++++++------------ 1 file changed, 45 insertions(+), 35 deletions(-) diff --git a/src/coreclr/vm/callstubgenerator.cpp b/src/coreclr/vm/callstubgenerator.cpp index 2394c5bacea3f1..30a70af7ace201 100644 --- a/src/coreclr/vm/callstubgenerator.cpp +++ b/src/coreclr/vm/callstubgenerator.cpp @@ -47,7 +47,7 @@ PCODE GPRegsRoutines[] = (PCODE)Load_RCX_RDX, // 01 (PCODE)Load_RCX_RDX_R8, // 02 (PCODE)Load_RCX_RDX_R8_R9, // 03 - (PCODE)0, // 10 + (PCODE)0, // 10 (PCODE)Load_RDX, // 11 (PCODE)Load_RDX_R8, // 12 (PCODE)Load_RDX_R8_R9, // 13 @@ -75,7 +75,7 @@ PCODE FPRegsRoutines[] = (PCODE)Load_XMM0_XMM1, // 01 (PCODE)Load_XMM0_XMM1_XMM2, // 02 (PCODE)Load_XMM0_XMM1_XMM2_XMM3, // 03 - (PCODE)0, // 10 + (PCODE)0, // 10 (PCODE)Load_XMM1, // 11 (PCODE)Load_XMM1_XMM2, // 12 (PCODE)Load_XMM1_XMM2_XMM3, // 13 @@ -121,7 +121,7 @@ PCODE GPRegsRoutines[] = (PCODE)Load_RDI_RSI_RDX_RCX, // 03 (PCODE)Load_RDI_RSI_RDX_RCX_R8, // 04 (PCODE)Load_RDI_RSI_RDX_RCX_R8_R9, // 05 - (PCODE)0, // 10 + (PCODE)0, // 10 (PCODE)Load_RSI, // 11 (PCODE)Load_RSI_RDX, // 12 (PCODE)Load_RSI_RDX_RCX, // 13 @@ -200,7 +200,7 @@ PCODE FPRegsRoutines[] = (PCODE)Load_XMM0_XMM1_XMM2_XMM3_XMM4_XMM5, // 05 (PCODE)Load_XMM0_XMM1_XMM2_XMM3_XMM4_XMM5_XMM6, // 06 (PCODE)Load_XMM0_XMM1_XMM2_XMM3_XMM4_XMM5_XMM6_XMM7,// 07 - (PCODE)0, // 10 + (PCODE)0, // 10 (PCODE)Load_XMM1, // 11 (PCODE)Load_XMM1_XMM2, // 12 (PCODE)Load_XMM1_XMM2_XMM3, // 13 @@ -321,7 +321,7 @@ PCODE GPRegsRoutines[] = (PCODE)Load_X0_X1_X2_X3_X4_X5, // 05 (PCODE)Load_X0_X1_X2_X3_X4_X5_X6, // 06 (PCODE)Load_X0_X1_X2_X3_X4_X5_X6_X7, // 07 - (PCODE)0, // 10 + (PCODE)0, // 10 (PCODE)Load_X1, // 11 (PCODE)Load_X1_X2, // 12 (PCODE)Load_X1_X2_X3, // 13 @@ -338,7 +338,7 @@ PCODE GPRegsRoutines[] = (PCODE)Load_X2_X3_X4_X5_X6, // 26 (PCODE)Load_X2_X3_X4_X5_X6_X7, // 27 (PCODE)0, // 30 - (PCODE)0, // 31 + (PCODE)0, // 31 (PCODE)0, // 32 (PCODE)Load_X3, // 33 (PCODE)Load_X3_X4, // 34 @@ -438,7 +438,7 @@ PCODE FPRegsRoutines[] = (PCODE)Load_D0_D1_D2_D3_D4_D5, // 05 (PCODE)Load_D0_D1_D2_D3_D4_D5_D6, // 06 (PCODE)Load_D0_D1_D2_D3_D4_D5_D6_D7, // 07 - (PCODE)0, // 10 + (PCODE)0, // 10 (PCODE)Load_D1, // 11 (PCODE)Load_D1_D2, // 12 (PCODE)Load_D1_D2_D3, // 13 @@ -455,7 +455,7 @@ PCODE FPRegsRoutines[] = (PCODE)Load_D2_D3_D4_D5_D6, // 26 (PCODE)Load_D2_D3_D4_D5_D6_D7, // 27 (PCODE)0, // 30 - (PCODE)0, // 31 + (PCODE)0, // 31 (PCODE)0, // 32 (PCODE)Load_D3, // 33 (PCODE)Load_D3_D4, // 34 @@ -590,7 +590,7 @@ CallStubHeader *CallStubGenerator::GenerateCallStub(MethodDesc *pMD, AllocMemTra ArgLocDesc argLocDesc; argIt.GetArgLoc(ofs, &argLocDesc); -#ifdef UNIX_AMD64_ABI +#ifdef UNIX_AMD64_ABI if (argIt.GetArgLocDescForStructInRegs() != NULL) { TypeHandle argTypeHandle; @@ -604,33 +604,43 @@ CallStubHeader *CallStubGenerator::GenerateCallStub(MethodDesc *pMD, AllocMemTra { ArgLocDesc argLocDescEightByte = {}; SystemVClassificationType eightByteType = pEEClass->GetEightByteClassification(i); - if (eightByteType == SystemVClassificationTypeInteger) - { - if (argLocDesc.m_cGenReg != 0) - { - argLocDescEightByte.m_cGenReg = 1; - argLocDescEightByte.m_idxGenReg = argLocDesc.m_idxGenReg++; - } - else - { - argLocDescEightByte.m_byteStackSize = 8; - argLocDescEightByte.m_byteStackIndex = argLocDesc.m_byteStackIndex; - argLocDesc.m_byteStackIndex += 8; - } - } - else if (eightByteType == SystemVClassificationTypeSSE) + switch (eightByteType) { - if (argLocDesc.m_cFloatReg != 0) + case SystemVClassificationTypeInteger: + case SystemVClassificationTypeIntegerReference: + case SystemVClassificationTypeIntegerByRef: { - argLocDescEightByte.m_cFloatReg = 1; - argLocDescEightByte.m_idxFloatReg = argLocDesc.m_idxFloatReg++; + if (argLocDesc.m_cGenReg != 0) + { + argLocDescEightByte.m_cGenReg = 1; + argLocDescEightByte.m_idxGenReg = argLocDesc.m_idxGenReg++; + } + else + { + argLocDescEightByte.m_byteStackSize = 8; + argLocDescEightByte.m_byteStackIndex = argLocDesc.m_byteStackIndex; + argLocDesc.m_byteStackIndex += 8; + } + break; } - else + case SystemVClassificationTypeSSE: { - argLocDescEightByte.m_byteStackSize = 8; - argLocDescEightByte.m_byteStackIndex = argLocDesc.m_byteStackIndex; - argLocDesc.m_byteStackIndex += 8; + if (argLocDesc.m_cFloatReg != 0) + { + argLocDescEightByte.m_cFloatReg = 1; + argLocDescEightByte.m_idxFloatReg = argLocDesc.m_idxFloatReg++; + } + else + { + argLocDescEightByte.m_byteStackSize = 8; + argLocDescEightByte.m_byteStackIndex = argLocDesc.m_byteStackIndex; + argLocDesc.m_byteStackIndex += 8; + } + break; } + default: + assert(!"Unhandled systemv classification for argument in GenerateCallStub"); + break; } ProcessArgument(argIt, argLocDescEightByte, pRoutines); } @@ -878,7 +888,7 @@ void CallStubGenerator::ProcessArgument(ArgIterator& argIt, ArgLocDesc& argLocDe } if (argLocDesc.m_cGenReg != 0) - { + { if (m_r1 == NoRange) // No active range yet { // Start a new range @@ -907,7 +917,7 @@ void CallStubGenerator::ProcessArgument(ArgIterator& argIt, ArgLocDesc& argLocDe // Start a new range m_x1 = argLocDesc.m_idxFloatReg; m_x2 = m_x1 + argLocDesc.m_cFloatReg - 1; - } + } else if (argLocDesc.m_idxFloatReg == m_x2 + 1) { // Extend an existing range @@ -929,7 +939,7 @@ void CallStubGenerator::ProcessArgument(ArgIterator& argIt, ArgLocDesc& argLocDe // Start a new range m_s1 = argLocDesc.m_byteStackIndex; m_s2 = m_s1 + argLocDesc.m_byteStackSize - 1; - } + } else if ((argLocDesc.m_byteStackIndex == m_s2 + 1) && (argLocDesc.m_byteStackSize >= 8)) { // Extend an existing range, but only if the argument is at least pointer size large. @@ -987,4 +997,4 @@ void CallStubGenerator::ProcessArgument(ArgIterator& argIt, ArgLocDesc& argLocDe #endif // UNIX_AMD64_ABI } -#endif // FEATURE_INTERPRETER \ No newline at end of file +#endif // FEATURE_INTERPRETER