Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ff64ccd
Implement simple version of On Stack Replacement (OSR)
AndyAyersMS Jan 8, 2020
9628962
fix initializer order
AndyAyersMS Feb 28, 2020
a168fe4
fix build issue when feature not defined
AndyAyersMS Feb 28, 2020
96338f9
fix another build issue
AndyAyersMS Feb 28, 2020
6e8e97f
WIP
AndyAyersMS Mar 4, 2020
270f3c7
more WIP; builds and seems to work
AndyAyersMS Mar 6, 2020
28b365e
Merge remote-tracking branch 'local0/master' into OSR-Revision
AndyAyersMS Mar 6, 2020
b1468e0
Introduce new opt tier for OSR, rework code version locking.
AndyAyersMS Mar 7, 2020
11c4edb
update crossgen2 for jit interface changes
AndyAyersMS Mar 7, 2020
2ae1fc8
remove unneeded change
AndyAyersMS Mar 7, 2020
d79997b
Merge branch 'master' into OnStackReplacement
AndyAyersMS Mar 7, 2020
6620f5c
always define PatchpointInfo struct
AndyAyersMS Mar 7, 2020
e8246a8
Revise how patchpoint info is stored in debug blob.
AndyAyersMS Mar 8, 2020
60da2b4
update doc
AndyAyersMS Mar 9, 2020
5b4ec2d
moving OSR runtime data to loader allocator
AndyAyersMS Mar 10, 2020
4e8e33f
logging
AndyAyersMS Mar 10, 2020
a75df6b
more doc updates
AndyAyersMS Mar 10, 2020
53f2144
feedback on jit changes
AndyAyersMS Mar 10, 2020
d9dcc20
reduce patchpoint info size
AndyAyersMS Mar 10, 2020
a96b1e7
Revise daczation of OnStackReplacementManager
AndyAyersMS Mar 10, 2020
d850137
Merge branch 'master' into OnStackReplacement
AndyAyersMS Mar 10, 2020
a1fef86
rework allocation of runtime data
AndyAyersMS Mar 11, 2020
c042f52
add debug check for scratch bb
AndyAyersMS Mar 11, 2020
13b4616
release mode fixes; move more to debug
AndyAyersMS Mar 11, 2020
aff5ebc
fix initializer order
AndyAyersMS Mar 11, 2020
9266816
fix test case
AndyAyersMS Mar 12, 2020
eef7ad5
review feedback
AndyAyersMS Mar 12, 2020
bab99a2
fix gcc build issue
AndyAyersMS Mar 12, 2020
b3ed095
Merge branch 'master' into OnStackReplacement
AndyAyersMS Mar 12, 2020
9a59878
keep two pointers on jit interface
AndyAyersMS Mar 13, 2020
a63bca1
review feedback
AndyAyersMS Mar 14, 2020
04cedab
no patchpoints if feature not defined
AndyAyersMS Mar 14, 2020
f8ad741
update test projects to enable OSR
AndyAyersMS Mar 14, 2020
9dfc823
Merge branch 'master' into OnStackReplacement
AndyAyersMS Mar 14, 2020
8a06e85
fix test project
AndyAyersMS Mar 15, 2020
7156042
don't over-allocate debug store size
AndyAyersMS Mar 16, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,111 changes: 1,111 additions & 0 deletions docs/design/features/OnStackReplacement.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/coreclr/clrdefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,9 @@ endif(FEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION)
add_definitions(-DFEATURE_SVR_GC)
add_definitions(-DFEATURE_SYMDIFF)
add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:CROSSGEN_COMPONENT>>>:FEATURE_TIERED_COMPILATION>)
if (CLR_CMAKE_TARGET_ARCH_AMD64)
add_compile_definitions($<$<NOT:$<BOOL:$<TARGET_PROPERTY:CROSSGEN_COMPONENT>>>:FEATURE_ON_STACK_REPLACEMENT>)
endif (CLR_CMAKE_TARGET_ARCH_AMD64)
if (CLR_CMAKE_TARGET_WIN32)
add_definitions(-DFEATURE_TYPEEQUIVALENCE)
endif(CLR_CMAKE_TARGET_WIN32)
Expand Down
32 changes: 32 additions & 0 deletions src/coreclr/src/ToolBox/superpmi/superpmi-shared/compileresult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,38 @@ bool CompileResult::repSetVars(CORINFO_METHOD_HANDLE* ftn, ULONG32* cVars, ICorD
return true;
}

// Note - Ownership of patchpointInfo is transfered with this call. In replay icorjitinfo we should free it.
void CompileResult::recSetPatchpointInfo(PatchpointInfo* patchpointInfo)
{
if (SetPatchpointInfo == nullptr)
SetPatchpointInfo = new LightWeightMap<DWORD, Agnostic_SetPatchpointInfo>();

Agnostic_SetPatchpointInfo value;
value.index = (DWORD)SetPatchpointInfo->AddBuffer((const unsigned char*) patchpointInfo, patchpointInfo->PatchpointInfoSize());
SetPatchpointInfo->Add(0, value);
}
void CompileResult::dmpSetPatchpointInfo(DWORD key, const Agnostic_SetPatchpointInfo& value)
{
PatchpointInfo* patchpointInfo = (PatchpointInfo*)SetPatchpointInfo->GetBuffer(value.index);
printf("SetPatchpointInfo key %u, index %u{", key, value.index);
// todo -- dump contents
printf("}");
SetPatchpointInfo->Unlock();
}
bool CompileResult::repSetPatchpointInfo(PatchpointInfo** patchpointInfo)
{
if ((SetPatchpointInfo == nullptr) || (SetPatchpointInfo->GetCount() == 0))
{
*patchpointInfo = nullptr;
return false;
}

Agnostic_SetPatchpointInfo value;
value = SetPatchpointInfo->Get(0);
*patchpointInfo = (PatchpointInfo*)SetPatchpointInfo->GetBuffer(value.index);
return true;
}

void CompileResult::recAllocGCInfo(size_t size, void* retval)
{
allocGCInfoDets.size = size;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ class CompileResult
DWORD cVars;
DWORD vars_offset;
};
struct Agnostic_SetPatchpointInfo
{
DWORD index;
};
struct Agnostic_CORINFO_EH_CLAUSE2
{
DWORD Flags;
Expand Down Expand Up @@ -200,6 +204,10 @@ class CompileResult
void dmpSetVars(DWORD key, const Agnostic_SetVars& value);
bool repSetVars(CORINFO_METHOD_HANDLE* ftn, ULONG32* cVars, ICorDebugInfo::NativeVarInfo** vars);

void recSetPatchpointInfo(PatchpointInfo* patchpointInfo);
void dmpSetPatchpointInfo(DWORD key, const Agnostic_SetPatchpointInfo& value);
bool repSetPatchpointInfo(PatchpointInfo** patchpointInfo);

void recAllocGCInfo(size_t size, void* retval);
void recAllocGCInfoCapture();
void dmpAllocGCInfo(DWORD key, const Agnostic_AllocGCInfo& value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ LWM(SetEHcount, DWORD, DWORD)
LWM(SetEHinfo, DWORD, CompileResult::Agnostic_CORINFO_EH_CLAUSE2)
LWM(SetMethodAttribs, DWORDLONG, DWORD)
LWM(SetVars, DWORD, CompileResult::Agnostic_SetVars)
LWM(SetPatchpointInfo, DWORD, CompileResult::Agnostic_SetPatchpointInfo)

#undef LWM
#undef DENSELWM
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,15 @@ void getGSCookie(GSCookie* pCookieVal, // OUT
GSCookie** ppCookieVal // OUT
);

// Provide patchpoint info for the method currently being jitted.
void setPatchpointInfo(
PatchpointInfo* patchpointInfo
);

PatchpointInfo* getOSRInfo(
unsigned * ilOffset // OUT
);

/**********************************************************************************/
//
// ICorModuleInfo
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ LWM(GetMethodSync, DWORDLONG, DLDL)
LWM(GetMethodVTableOffset, DWORDLONG, DDD)
LWM(GetNewArrHelper, DWORDLONG, DWORD)
LWM(GetNewHelper, Agnostic_GetNewHelper, DD)
LWM(GetOSRInfo, DWORD, Agnostic_GetOSRInfo)
LWM(GetParentType, DWORDLONG, DWORDLONG)
LWM(GetProfilingHandle, DWORD, Agnostic_GetProfilingHandle)
LWM(GetReadyToRunHelper, GetReadyToRunHelper_TOKENin, GetReadyToRunHelper_TOKENout)
Expand Down Expand Up @@ -152,5 +153,6 @@ LWM(TryResolveToken, Agnostic_CORINFO_RESOLVED_TOKENin, TryResolveTokenValue)
LWM(SatisfiesClassConstraints, DWORDLONG, DWORD)
LWM(SatisfiesMethodConstraints, DLDL, DWORD)


#undef LWM
#undef DENSELWM
34 changes: 34 additions & 0 deletions src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@ void MethodContext::repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags)
info->locals.pSig = (PCCOR_SIGNATURE)CompileMethod->GetBuffer(value.info.locals.pSig_Index);
info->locals.scope = (CORINFO_MODULE_HANDLE)value.info.locals.scope;
info->locals.token = (mdToken)value.info.locals.token;

*flags = (unsigned)value.flags;
DEBUG_REP(dmpCompileMethod(0, value));
}
Expand Down Expand Up @@ -3965,6 +3966,39 @@ void MethodContext::repGetGSCookie(GSCookie* pCookieVal, GSCookie** ppCookieVal)
*ppCookieVal = (GSCookie*)value.B;
}

void MethodContext::recGetOSRInfo(PatchpointInfo* patchpointInfo, unsigned* ilOffset)
{
if (GetOSRInfo == nullptr)
{
GetOSRInfo = new LightWeightMap<DWORD, Agnostic_GetOSRInfo>();
}

Agnostic_GetOSRInfo value;

value.index = (DWORD)GetOSRInfo->AddBuffer((const unsigned char*) patchpointInfo, patchpointInfo->PatchpointInfoSize());
value.ilOffset = *ilOffset;

// use 0 for key
DWORD key = 0;
GetOSRInfo->Add(key, value);
DEBUG_REC(dmpGetOSRInfo(key, value));
}

void MethodContext::dmpGetOSRInfo(DWORD key, const Agnostic_GetOSRInfo& value)
{
// todo - dump patchpoint info?
printf("GetOSRInfo key %u, value patchpointInfo-%u {...} iloffset-%u\n",
key, value.index, value.ilOffset);
}

PatchpointInfo* MethodContext::repGetOSRInfo(unsigned* ilOffset)
{
DWORD key = 0;
Agnostic_GetOSRInfo value = GetOSRInfo->Get(key);
*ilOffset = value.ilOffset;
return (PatchpointInfo*)GetOSRInfo->GetBuffer(value.index);
}

void MethodContext::recGetClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls,
CORINFO_MODULE_HANDLE* pModule,
void** ppIndirection,
Expand Down
13 changes: 12 additions & 1 deletion src/coreclr/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ class MethodContext
DWORD targetAbi;
DWORD osType;
};
struct Agnostic_GetOSRInfo
{
DWORD index;
unsigned ilOffset;
};
struct Agnostic_GetFieldAddress
{
DWORDLONG ppIndirection;
Expand Down Expand Up @@ -986,6 +991,10 @@ class MethodContext
void dmpGetGSCookie(DWORD key, DLDL value);
void repGetGSCookie(GSCookie* pCookieVal, GSCookie** ppCookieVal);

void recGetOSRInfo(PatchpointInfo* patchpointInfo, unsigned* ilOffset);
void dmpGetOSRInfo(DWORD key, const Agnostic_GetOSRInfo& value);
PatchpointInfo* repGetOSRInfo(unsigned* ilOffset);

void recGetClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls,
CORINFO_MODULE_HANDLE* pModule,
void** ppIndirection,
Expand Down Expand Up @@ -1309,7 +1318,7 @@ class MethodContext
};

// ********************* Please keep this up-to-date to ease adding more ***************
// Highest packet number: 175
// Highest packet number: 177
// *************************************************************************************
enum mcPackets
{
Expand Down Expand Up @@ -1420,6 +1429,7 @@ enum mcPackets
Packet_GetMethodVTableOffset = 78,
Packet_GetNewArrHelper = 79,
Packet_GetNewHelper = 80,
Packet_GetOSRInfo = 177, // Added 3/5/2020
Packet_GetParentType = 81,
Packet_GetPInvokeUnmanagedTarget = 82, // Retired 2/18/2020
Packet_GetProfilingHandle = 83,
Expand Down Expand Up @@ -1487,6 +1497,7 @@ enum mcPackets
PacketCR_SetEHinfo = 128,
PacketCR_SetMethodAttribs = 129,
PacketCR_SetVars = 130,
PacketCR_SetPatchpointInfo = 176, // added 8/5/2019
PacketCR_RecordCallSite = 146, // Added 10/28/2013 - to support indirect calls
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <mscoree.h>
#include <corjit.h>
#include <utilcode.h>
#include <patchpointinfo.h>

/// Turn back on direct access to a few OS level things...
#undef HeapCreate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,23 @@ void interceptor_ICJI::getGSCookie(GSCookie* pCookieVal, // OUT
mc->recGetGSCookie(pCookieVal, ppCookieVal);
}

// Provide patchpoint info for the method currently being jitted.
void interceptor_ICJI::setPatchpointInfo(PatchpointInfo* patchpointInfo)
{
mc->cr->AddCall("setPatchpointInfo");
mc->cr->recSetPatchpointInfo(patchpointInfo); // Since the EE frees, we've gotta record before its sent to the EE.
original_ICorJitInfo->setPatchpointInfo(patchpointInfo);
}

// Get OSR info for the method currently being jitted
PatchpointInfo* interceptor_ICJI::getOSRInfo(unsigned* ilOffset)
{
mc->cr->AddCall("getOSRInfo");
PatchpointInfo* patchpointInfo = original_ICorJitInfo->getOSRInfo(ilOffset);
mc->recGetOSRInfo(patchpointInfo, ilOffset);
return patchpointInfo;
}

/**********************************************************************************/
//
// ICorModuleInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,20 @@ void interceptor_ICJI::getGSCookie(GSCookie* pCookieVal, // OUT
original_ICorJitInfo->getGSCookie(pCookieVal, ppCookieVal);
}

// Provide patchpoint info for the method currently being jitted.
void interceptor_ICJI::setPatchpointInfo(PatchpointInfo* patchpointInfo)
{
mcs->AddCall("setPatchpointInfo");
original_ICorJitInfo->setPatchpointInfo(patchpointInfo);
}

// Get OSR info for the method currently being jitted
PatchpointInfo* interceptor_ICJI::getOSRInfo(unsigned* ilOffset)
{
mcs->AddCall("getOSRInfo");
return original_ICorJitInfo->getOSRInfo(ilOffset);
}

/**********************************************************************************/
//
// ICorModuleInfo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,19 @@ void interceptor_ICJI::getGSCookie(GSCookie* pCookieVal, // OUT
original_ICorJitInfo->getGSCookie(pCookieVal, ppCookieVal);
}


// Provide patchpoint info for the method currently being jitted.
void interceptor_ICJI::setPatchpointInfo(PatchpointInfo* patchpointInfo)
{
original_ICorJitInfo->setPatchpointInfo(patchpointInfo);
}

// Get OSR info for the method currently being jitted
PatchpointInfo* interceptor_ICJI::getOSRInfo(unsigned* ilOffset)
{
return original_ICorJitInfo->getOSRInfo(ilOffset);
}

/**********************************************************************************/
//
// ICorModuleInfo
Expand Down
15 changes: 15 additions & 0 deletions src/coreclr/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,21 @@ void MyICJI::getGSCookie(GSCookie* pCookieVal, // OUT
jitInstance->mc->repGetGSCookie(pCookieVal, ppCookieVal);
}

// Provide patchpoint info for the method currently being jitted.
void MyICJI::setPatchpointInfo(PatchpointInfo* patchpointInfo)
{
jitInstance->mc->cr->AddCall("setPatchpointInfo");
jitInstance->mc->cr->recSetPatchpointInfo(patchpointInfo);
freeArray(patchpointInfo); // See note in recSetPatchpointInfo... we own destroying this array
}

// Get OSR info for the method currently being jitted
PatchpointInfo* MyICJI::getOSRInfo(unsigned* ilOffset)
{
jitInstance->mc->cr->AddCall("getOSRInfo");
return jitInstance->mc->repGetOSRInfo(ilOffset);
}

/**********************************************************************************/
//
// ICorModuleInfo
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/src/inc/CrstTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,10 @@ End
Crst JitGenericHandleCache
End

Crst JitPatchpoint
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe could reuse CrstLeafLock instead, as there appear to be are many different locks in that class

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can no longer be a leaf lock as we have to allocate while holding.

AcquiredBefore LoaderHeap
End

Crst JitPerf
Unordered
End
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/src/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,16 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_TC_DeleteCallCountingStubsAfter, W("TC_DeleteC
#endif
#endif

///
/// On-Stack Replacement
///
#ifdef FEATURE_ON_STACK_REPLACEMENT
RETAIL_CONFIG_DWORD_INFO(INTERNAL_OSR_CounterBump, W("OSR_CounterBump"), 1000, "Counter reload value when a patchpoint is hit")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_OSR_HitLimit, W("OSR_HitLimit"), 10, "Number of times a patchpoint must call back to trigger an OSR transition")
CONFIG_DWORD_INFO(INTERNAL_OSR_LowId, W("OSR_LowId"), (DWORD)-1, "Low end of enabled patchpoint range (inclusive)");
CONFIG_DWORD_INFO(INTERNAL_OSR_HighId, W("OSR_HighId"), 10000000, "High end of enabled patchpoint range (inclusive)");
#endif

///
/// Entry point slot backpatch
///
Expand Down
27 changes: 22 additions & 5 deletions src/coreclr/src/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,11 @@ TODO: Talk about initializing strutures before use
#endif
#endif

SELECTANY const GUID JITEEVersionIdentifier = { /* b2e40020-6125-41e4-a0fc-821127ec192a */
0xb2e40020,
0x6125,
0x41e4,
{0xa0, 0xfc, 0x82, 0x11, 0x27, 0xec, 0x19, 0x2a}
SELECTANY const GUID JITEEVersionIdentifier = { /* c231d2d7-4764-4097-a9ef-5961041540df */
0xc231d2d7,
0x4764,
0x4097,
{0xa9, 0xef, 0x59, 0x61, 0x04, 0x15, 0x40, 0xdf}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -631,6 +631,8 @@ enum CorInfoHelpFunc

CORINFO_HELP_STACK_PROBE, // Probes each page of the allocated stack frame

CORINFO_HELP_PATCHPOINT, // Notify runtime that code has reached a patchpoint

CORINFO_HELP_COUNT,
};

Expand Down Expand Up @@ -1083,6 +1085,11 @@ inline bool dontInline(CorInfoInline val) {
return(val < 0);
}

// Patchpoint info is passed back and forth across the interface
// but is opaque.

struct PatchpointInfo;

// Cookie types consumed by the code generator (these are opaque values
// not inspected by the code generator):

Expand Down Expand Up @@ -2145,6 +2152,16 @@ class ICorStaticInfo
GSCookie ** ppCookieVal // OUT
) = 0;

// Provide patchpoint info for the method currently being jitted.
virtual void setPatchpointInfo(
PatchpointInfo* patchpointInfo
) = 0;

// Get patchpoint info and il offset for the method currently being jitted.
virtual PatchpointInfo* getOSRInfo(
unsigned *ilOffset // [OUT] il offset of OSR entry point
) = 0;

/**********************************************************************************/
//
// ICorModuleInfo
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/inc/corjitflags.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class CORJIT_FLAGS

#endif // !defined(TARGET_X86)

CORJIT_FLAG_UNUSED6 = 13,
CORJIT_FLAG_OSR = 13, // Generate alternate method for On Stack Replacement

#if defined(TARGET_X86) || defined(TARGET_AMD64)

Expand Down
Loading