Skip to content

Commit 63d560a

Browse files
Make coreclr_initialize run cleanly for corewasmrun (#119217)
* Separate call invokers between JIT compatible interpreter and interpreter with Portable EntryPoints. * Handle native helpers with portable entry points * Add simple interpreter managed frame stack walker when native assert fires. This will help debugging asserts in interpreter scenarios. --------- Co-authored-by: Jan Kotas <[email protected]>
1 parent b9fbc0d commit 63d560a

20 files changed

+655
-232
lines changed

src/coreclr/debug/daccess/daccess.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5635,7 +5635,7 @@ ClrDataAccess::GetJitHelperName(
56355635

56365636
for (int i = 0; i < CORINFO_HELP_COUNT; i++)
56375637
{
5638-
if (address == (TADDR)(pTable[i].pfnHelper))
5638+
if (address == pTable[i].pfnHelper)
56395639
return s_rgHelperNames[i];
56405640
}
56415641
}
@@ -5652,7 +5652,7 @@ ClrDataAccess::GetJitHelperName(
56525652
PTR_READ(dac_cast<TADDR>(&hlpDynamicFuncTable), DYNAMIC_CORINFO_HELP_COUNT * sizeof(VMHELPDEF)));
56535653
for (unsigned d = 0; d < DYNAMIC_CORINFO_HELP_COUNT; d++)
56545654
{
5655-
if (address == (TADDR)(pDynamicTable[d].pfnHelper))
5655+
if (address == pDynamicTable[d].pfnHelper)
56565656
{
56575657
return s_rgHelperNames[s_rgDynamicHCallIds[d]];
56585658
}
@@ -5991,7 +5991,7 @@ ClrDataAccess::GetMethodVarInfo(MethodDesc* methodDesc,
59915991
BOOL success = DebugInfoManager::GetBoundariesAndVars(
59925992
request,
59935993
DebugInfoStoreNew, NULL, // allocator
5994-
BoundsType::Instrumented,
5994+
BoundsType::Instrumented,
59955995
NULL, NULL,
59965996
&countNativeVarInfo, &nativeVars);
59975997

src/coreclr/debug/ee/controller.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -210,13 +210,13 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu
210210
//
211211

212212
BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer;
213-
213+
214214
// Overwrite the *signed* displacement.
215215
int dwOldDisp = *(int*)(&patchBypassRX[instrAttrib.m_dwOffsetToDisp]);
216216
int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) -
217217
(offsetof(SharedPatchBypassBuffer, PatchBypass) + instrAttrib.m_cbInstr);
218218
*(int*)(&patchBypassRW[instrAttrib.m_dwOffsetToDisp]) = dwNewDisp;
219-
219+
220220
// This could be an LEA, which we'll just have to change into a MOV and copy the original address.
221221
if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d))
222222
{
@@ -229,7 +229,7 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu
229229
_ASSERTE(instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass);
230230
// Copy the data into our buffer.
231231
memcpy(bufferBypassRW, this->address + instrAttrib.m_cbInstr + dwOldDisp, instrAttrib.m_cOperandSize);
232-
232+
233233
if (instrAttrib.m_fIsWrite)
234234
{
235235
// save the actual destination address and size so when we TriggerSingleStep() we can update the value
@@ -238,17 +238,17 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu
238238
}
239239
}
240240
}
241-
241+
242242
#endif // TARGET_AMD64
243243

244244
m_pSharedPatchBypassBuffer->SetInstructionAttrib(instrAttrib);
245-
245+
246246
// Since we just created a new buffer of code, but the CPU caches code and may
247247
// not be aware of our changes. This should force the CPU to dump any cached
248248
// instructions it has in this region and load the new ones from memory
249249
FlushInstructionCache(GetCurrentProcess(), patchBypassRW + CORDbg_BREAK_INSTRUCTION_SIZE,
250250
MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE);
251-
251+
252252
return m_pSharedPatchBypassBuffer;
253253
}
254254
#endif // !FEATURE_EMULATE_SINGLESTEP
@@ -2405,29 +2405,29 @@ static bool _AddrIsJITHelper(PCODE addr)
24052405
{
24062406
for (int i = 0; i < CORINFO_HELP_COUNT; i++)
24072407
{
2408-
if (hlpFuncTable[i].pfnHelper == (void*)addr)
2408+
if (hlpFuncTable[i].pfnHelper == addr)
24092409
{
24102410
LOG((LF_CORDB, LL_INFO10000,
2411-
"_ANIM: address of helper function found: 0x%08x\n",
2411+
"_ANIM: address of helper function found: 0x%zx\n",
24122412
addr));
24132413
return true;
24142414
}
24152415
}
24162416

24172417
for (unsigned d = 0; d < DYNAMIC_CORINFO_HELP_COUNT; d++)
24182418
{
2419-
if (hlpDynamicFuncTable[d].pfnHelper == (void*)addr)
2419+
if (hlpDynamicFuncTable[d].pfnHelper == addr)
24202420
{
24212421
LOG((LF_CORDB, LL_INFO10000,
2422-
"_ANIM: address of helper function found: 0x%08x\n",
2422+
"_ANIM: address of helper function found: 0x%zx\n",
24232423
addr));
24242424
return true;
24252425
}
24262426
}
24272427

24282428
LOG((LF_CORDB, LL_INFO10000,
24292429
"_ANIM: address within runtime dll, but not a helper function "
2430-
"0x%08x\n", addr));
2430+
"0x%zx\n", addr));
24312431
}
24322432
#else // !defined(HOST_64BIT) && !defined(TARGET_UNIX)
24332433
// TODO: Figure out what we want to do here

src/coreclr/inc/regdisp.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,9 @@ inline void FillContextPointers(PT_KNONVOLATILE_CONTEXT_POINTERS pCtxPtrs, PT_CO
471471
*(&pCtxPtrs->Tp) = &pCtx->Tp;
472472
*(&pCtxPtrs->Fp) = &pCtx->Fp;
473473
*(&pCtxPtrs->Ra) = &pCtx->Ra;
474-
#else // TARGET_RISCV64
474+
#elif defined(TARGET_WASM)
475+
// Wasm doesn't have registers
476+
#else // TARGET_WASM
475477
PORTABILITY_ASSERT("FillContextPointers");
476478
#endif // _TARGET_???_ (ELSE)
477479
}

src/coreclr/pal/src/arch/wasm/stubs.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,16 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do
88

99
/* debugbreak */
1010

11+
#ifdef _DEBUG
12+
extern void DBG_PrintInterpreterStack();
13+
#endif // _DEBUG
14+
1115
extern "C" void
1216
DBG_DebugBreak()
1317
{
18+
#ifdef _DEBUG
19+
DBG_PrintInterpreterStack();
20+
#endif // _DEBUG
1421
asm volatile ("unreachable");
1522
}
1623

src/coreclr/vm/callhelpers.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ void* DispatchCallSimple(
225225
callDescrData.pTarget = pTargetAddress;
226226

227227
#ifdef TARGET_WASM
228-
PORTABILITY_ASSERT("wasm need to fill call description data");
229-
#endif
228+
callDescrData.nArgsSize = numStackSlotsToCopy * sizeof(ARGHOLDER_TYPE);
229+
#endif // TARGET_WASM
230230

231231
if ((dwDispatchCallSimpleFlags & DispatchCallSimple_CatchHandlerFoundNotification) != 0)
232232
{
@@ -519,9 +519,6 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
519519
CallDescrData callDescrData;
520520

521521
callDescrData.pSrc = pTransitionBlock + sizeof(TransitionBlock);
522-
#ifdef TARGET_WASM
523-
callDescrData.pTransitionBlock = (TransitionBlock*)pTransitionBlock;
524-
#endif
525522
_ASSERTE((nStackBytes % TARGET_POINTER_SIZE) == 0);
526523
callDescrData.numStackSlots = nStackBytes / TARGET_POINTER_SIZE;
527524
#ifdef CALLDESCR_ARGREGS
@@ -539,9 +536,8 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT *
539536
callDescrData.fpReturnSize = fpReturnSize;
540537
callDescrData.pTarget = m_pCallTarget;
541538
#ifdef TARGET_WASM
542-
callDescrData.pMD = m_pMD;
543539
callDescrData.nArgsSize = m_argIt.GetArgSize();
544-
#endif
540+
#endif // TARGET_WASM
545541

546542
CallDescrWorkerWithHandler(&callDescrData);
547543

src/coreclr/vm/callhelpers.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,8 @@ struct CallDescrData
2929
UINT32 fpReturnSize;
3030
PCODE pTarget;
3131
#ifdef TARGET_WASM
32-
// method description is used to compile the method with the interpreter
33-
MethodDesc* pMD;
3432
// size of the arguments and the transition block are used to execute the method with the interpreter
3533
size_t nArgsSize;
36-
TransitionBlock* pTransitionBlock;
3734
#endif
3835

3936
#ifdef CALLDESCR_RETBUFFARGREG

src/coreclr/vm/callingconvention.h

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
#ifndef __CALLING_CONVENTION_INCLUDED
1313
#define __CALLING_CONVENTION_INCLUDED
1414

15+
#ifdef FEATURE_INTERPRETER
16+
#include "../../interpreter/interpretershared.h"
17+
#endif // FEATURE_INTERPRETER
18+
1519
BOOL IsRetBuffPassedAsFirstArg();
1620

1721
// Describes how a single argument is laid out in registers and/or stack locations when given as an input to a
@@ -491,31 +495,31 @@ class ArgIteratorTemplate : public ARGITERATOR_BASE
491495

492496
while (typ == ELEMENT_TYPE_VALUETYPE &&
493497
pMT->GetNumInstanceFields() == 1 && (!pMT->HasLayout() ||
494-
pMT->GetNumInstanceFieldBytes() == 4
495-
)) // Don't do the optimization if we're getting specified anything but the trivial layout.
496-
{
497-
FieldDesc * pFD = pMT->GetApproxFieldDescListRaw();
498+
pMT->GetNumInstanceFieldBytes() == 4
499+
)) // Don't do the optimization if we're getting specified anything but the trivial layout.
500+
{
501+
FieldDesc * pFD = pMT->GetApproxFieldDescListRaw();
498502
CorElementType type = pFD->GetFieldType();
499503

500504
bool exitLoop = false;
501-
switch (type)
505+
switch (type)
502506
{
503507
case ELEMENT_TYPE_VALUETYPE:
504508
{
505-
//@todo: Is it more apropos to call LookupApproxFieldTypeHandle() here?
506-
TypeHandle fldHnd = pFD->GetApproxFieldTypeHandleThrowing();
509+
//@todo: Is it more apropos to call LookupApproxFieldTypeHandle() here?
510+
TypeHandle fldHnd = pFD->GetApproxFieldTypeHandleThrowing();
507511
CONSISTENCY_CHECK(!fldHnd.IsNull());
508512
pMT = fldHnd.GetMethodTable();
509513
FALLTHROUGH;
510-
}
514+
}
511515
case ELEMENT_TYPE_PTR:
512516
case ELEMENT_TYPE_I:
513517
case ELEMENT_TYPE_U:
514-
case ELEMENT_TYPE_I4:
518+
case ELEMENT_TYPE_I4:
515519
case ELEMENT_TYPE_U4:
516-
{
520+
{
517521
typ = type;
518-
break;
522+
break;
519523
}
520524
default:
521525
exitLoop = true;
@@ -853,7 +857,7 @@ class ArgIteratorTemplate : public ARGITERATOR_BASE
853857
pLoc->m_idxFloatReg = floatRegOfsInBytes / FLOAT_REGISTER_SIZE;
854858
pLoc->m_cFloatReg = 1;
855859
}
856-
else
860+
else
857861
#endif // UNIX_AMD64_ABI
858862
if (!TransitionBlock::IsStackArgumentOffset(argOffset))
859863
{
@@ -1874,11 +1878,11 @@ int ArgIteratorTemplate<ARGITERATOR_BASE>::GetNextOffset()
18741878

18751879
return argOfs;
18761880
#elif defined(TARGET_WASM)
1877-
int cbArg = ALIGN_UP(StackElemSize(argSize), TARGET_POINTER_SIZE);
1881+
int cbArg = ALIGN_UP(argSize, INTERP_STACK_SLOT_SIZE);
18781882
int argOfs = TransitionBlock::GetOffsetOfArgs() + m_ofsStack;
1879-
1883+
18801884
m_ofsStack += cbArg;
1881-
1885+
18821886
return argOfs;
18831887
#else
18841888
PORTABILITY_ASSERT("ArgIteratorTemplate::GetNextOffset");

src/coreclr/vm/dllimport.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5654,6 +5654,9 @@ PCODE PInvoke::GetStubForILStub(PInvokeMethodDesc* pNMD, MethodDesc** ppStubMD,
56545654
// varargs goes through vararg PInvoke stub
56555655
//
56565656
pStub = TheVarargPInvokeStub(pNMD->HasRetBuffArg());
5657+
5658+
// Only vararg P/Invoke use shared stubs, they need a precode to push the hidden argument.
5659+
(void)pNMD->GetOrCreatePrecode();
56575660
}
56585661

56595662
if (pNMD->IsEarlyBound())

0 commit comments

Comments
 (0)