Skip to content

Commit

Permalink
Fix SuperPMI collect with getIntConfigValue (#53442)
Browse files Browse the repository at this point in the history
* Fix SuperPMI collect with getIntConfigValue

PR #52427 introduced a per-compilation call to getIntConfigValue
on "SuperPMIMethodContextNumber". This pseudo-config should not
be collected. It exposed a pre-existing multi-threading issue in
the superpmi collector shim. I got rid of the per-compilation
override of the jithost MethodContext, which is problematic, and
currently unneeded, but documented the considerations around collecting
per-compilation data.

Fixes #53440

* Update src/coreclr/ToolBox/superpmi/superpmi-shim-collector/jithost.cpp

Co-authored-by: Kunal Pathak <Kunal.Pathak@microsoft.com>

Co-authored-by: Kunal Pathak <Kunal.Pathak@microsoft.com>
  • Loading branch information
BruceForstall and kunalspathak authored May 28, 2021
1 parent 9580011 commit 1ffa574
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp,
our_ICorJitInfo.original_ICorJitInfo = comp;

auto* mc = new MethodContext();
if (g_ourJitHost != nullptr)
{
g_ourJitHost->setMethodContext(mc);
}

our_ICorJitInfo.mc = mc;
our_ICorJitInfo.mc->cr->recProcessName(GetCommandLineA());

Expand Down Expand Up @@ -74,11 +69,6 @@ CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp,

delete mc;

if (g_ourJitHost != nullptr)
{
g_ourJitHost->setMethodContext(g_globalContext);
}

return temp;
}

Expand Down
28 changes: 23 additions & 5 deletions src/coreclr/ToolBox/superpmi/superpmi-shim-collector/jithost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@
#include "spmiutil.h"
#include "jithost.h"

// There is a single JitHost object created during the one-time initialization of the JIT (function jitStartup),
// and shared amongst all subsequent compilations. Any calls to the getIntConfigValue/getStringConfigValue
// APIs get recorded in a single, global MethodContext/CompileResult, and are copied to the
// per-compilation MethodContext in the shim implementation of compileMethod (using recGlobalContext()).
// This works because the JIT eagerly asks for all config values once, in the one-time jitStartup
// function. If the JIT were to ask for config values later, during the per-compilation phase,
// they would get recorded here in the global MethodContext, and copied to all subsequent
// compilation MethodContexts. This would be incorrect. A solution would be to use a per-compilation
// MethodContext in addition to the global MethodContext, but we have to allow for multi-threading. That is,
// there could be multiple JIT compilations happening concurrently, so we can't just replace the global
// MethodContext with a per-compilation MethodContext. Perhaps per-compilation MethodContext could be
// stored in a map from OS thread id to MethodContext, and looked up here based on thread id. The host APIs
// have no per-compilation knowledge.

JitHost* g_ourJitHost;

// RecordVariable: return `true` if the given COMPlus variable `key` should be recorded
Expand Down Expand Up @@ -39,11 +53,6 @@ JitHost::JitHost(ICorJitHost* wrappedHost, MethodContext* methodContext) : wrapp
{
}

void JitHost::setMethodContext(MethodContext* methodContext)
{
this->mc = methodContext;
}

void* JitHost::allocateMemory(size_t size)
{
return wrappedHost->allocateMemory(size);
Expand All @@ -56,6 +65,15 @@ void JitHost::freeMemory(void* block)

int JitHost::getIntConfigValue(const WCHAR* key, int defaultValue)
{
// Special-case handling: don't collect this pseudo-variable, and don't
// even record that it was called (since it would get recorded into the
// global state). (See the superpmi.exe tool implementation of JitHost::getIntConfigValue()
// for the special-case implementation of this.)
if (wcscmp(key, W("SuperPMIMethodContextNumber")) == 0)
{
return defaultValue;
}

mc->cr->AddCall("getIntConfigValue");
int result = wrappedHost->getIntConfigValue(key, defaultValue);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ class JitHost : public ICorJitHost
public:
JitHost(ICorJitHost* wrappedHost, MethodContext* methodContext);

void setMethodContext(MethodContext* methodContext);

#include "icorjithostimpl.h"

private:
Expand Down

0 comments on commit 1ffa574

Please sign in to comment.