Skip to content

Commit

Permalink
JIT: Initialize jitstdout lazily (#92123)
Browse files Browse the repository at this point in the history
Avoid duplicating a handle and doing several I/O operations on the
startup path. Fixes #91856 as a side effect.
  • Loading branch information
jakobbotsch authored Sep 19, 2023
1 parent 58fb822 commit 5ba46f0
Show file tree
Hide file tree
Showing 13 changed files with 238 additions and 209 deletions.
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2011,7 +2011,7 @@ void CodeGen::genEmitMachineCode()
#if TRACK_LSRA_STATS
if (JitConfig.DisplayLsraStats() == 3)
{
compiler->m_pLinearScan->dumpLsraStatsSummary(jitstdout);
compiler->m_pLinearScan->dumpLsraStatsSummary(jitstdout());
}
#endif // TRACK_LSRA_STATS

Expand Down Expand Up @@ -2104,7 +2104,7 @@ void CodeGen::genEmitUnwindDebugGCandEH()
genCreateAndStoreGCInfo(codeSize, prologSize, epilogSize DEBUGARG(codePtr));

#ifdef DEBUG
FILE* dmpf = jitstdout;
FILE* dmpf = jitstdout();

compiler->opts.dmpHex = false;
if (!strcmp(compiler->info.compMethodName, "<name of method you want the hex dump for"))
Expand Down Expand Up @@ -2157,7 +2157,7 @@ void CodeGen::genEmitUnwindDebugGCandEH()
fflush(dmpf);
}

if (dmpf != jitstdout)
if (dmpf != jitstdout())
{
fclose(dmpf);
}
Expand Down
342 changes: 170 additions & 172 deletions src/coreclr/jit/compiler.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -10351,7 +10351,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
InlineInfo* inlineInfo);
void compDone();

static void compDisplayStaticSizes(FILE* fout);
static void compDisplayStaticSizes();

//------------ Some utility functions --------------

Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1478,12 +1478,12 @@ void DisAssembler::disAsmCode(BYTE* hotCodePtr, size_t hotCodeSize, BYTE* coldCo
}
#else // !DEBUG
// NOTE: non-DEBUG builds always use jitstdout currently!
disAsmFile = jitstdout;
disAsmFile = jitstdout();
#endif // !DEBUG

if (disAsmFile == nullptr)
{
disAsmFile = jitstdout;
disAsmFile = jitstdout();
}

// As this writes to a common file, this is not reentrant.
Expand Down Expand Up @@ -1519,7 +1519,7 @@ void DisAssembler::disAsmCode(BYTE* hotCodePtr, size_t hotCodeSize, BYTE* coldCo
DisasmBuffer(disAsmFile, /* printIt */ true);
fprintf(disAsmFile, "\n");

if (disAsmFile != jitstdout)
if (disAsmFile != jitstdout())
{
fclose(disAsmFile);
}
Expand Down
66 changes: 46 additions & 20 deletions src/coreclr/jit/ee_il_dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

/*****************************************************************************/

FILE* jitstdout = nullptr;

ICorJitHost* g_jitHost = nullptr;
bool g_jitInitialized = false;

Expand Down Expand Up @@ -71,16 +69,25 @@ extern "C" DLLEXPORT void jitStartup(ICorJitHost* jitHost)

assert(!JitConfig.isInitialized());
JitConfig.initialize(jitHost);
Compiler::compStartup();

g_jitInitialized = true;
}

static FILE* volatile s_jitstdout;

static FILE* jitstdoutInit()
{
const WCHAR* jitStdOutFile = JitConfig.JitStdOutFile();
FILE* file = nullptr;
if (jitStdOutFile != nullptr)
{
jitstdout = _wfopen(jitStdOutFile, W("a"));
assert(jitstdout != nullptr);
file = _wfopen(jitStdOutFile, W("a"));
assert(file != nullptr);
}

#if !defined(HOST_UNIX)
if (jitstdout == nullptr)
if (file == nullptr)
{
int stdoutFd = _fileno(procstdout());
// Check fileno error output(s) -1 may overlap with errno result
Expand All @@ -89,43 +96,61 @@ extern "C" DLLEXPORT void jitStartup(ICorJitHost* jitHost)
// or bogus and avoid making further calls.
if ((stdoutFd != -1) && (stdoutFd != -2) && (errno != EINVAL))
{
int jitstdoutFd = _dup(_fileno(procstdout()));
int jitstdoutFd = _dup(stdoutFd);
// Check the error status returned by dup.
if (jitstdoutFd != -1)
{
_setmode(jitstdoutFd, _O_TEXT);
jitstdout = _fdopen(jitstdoutFd, "w");
assert(jitstdout != nullptr);
file = _fdopen(jitstdoutFd, "w");
assert(file != nullptr);

// Prevent the FILE* from buffering its output in order to avoid calls to
// `fflush()` throughout the code.
setvbuf(jitstdout, nullptr, _IONBF, 0);
setvbuf(file, nullptr, _IONBF, 0);
}
}
}
#endif // !HOST_UNIX

// If jitstdout is still null, fallback to whatever procstdout() was
// initially set to.
if (jitstdout == nullptr)
if (file == nullptr)
{
jitstdout = procstdout();
file = procstdout();
}

Compiler::compStartup();
FILE* observed = InterlockedCompareExchangeT(&s_jitstdout, file, nullptr);

g_jitInitialized = true;
if (observed != nullptr)
{
if (file != procstdout())
{
fclose(file);
}

return observed;
}

return file;
}

#ifndef DEBUG
FILE* jitstdout()
{
FILE* file = s_jitstdout;
if (file != nullptr)
{
return file;
}

return jitstdoutInit();
}

// Like printf/logf, but only outputs to jitstdout -- skips call back into EE.
void jitprintf(const char* fmt, ...)
{
va_list vl;
va_start(vl, fmt);
vfprintf(jitstdout, fmt, vl);
vfprintf(jitstdout(), fmt, vl);
va_end(vl);
}
#endif

void jitShutdown(bool processIsTerminating)
{
Expand All @@ -136,14 +161,15 @@ void jitShutdown(bool processIsTerminating)

Compiler::compShutdown();

if (jitstdout != procstdout())
FILE* file = s_jitstdout;
if ((file != nullptr) && (file != procstdout()))
{
// When the process is terminating, the fclose call is unnecessary and is also prone to
// crashing since the UCRT itself often frees the backing memory earlier on in the
// termination sequence.
if (!processIsTerminating)
{
fclose(jitstdout);
fclose(file);
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ unsigned emitter::emitInt32CnsCnt;
unsigned emitter::emitNegCnsCnt;
unsigned emitter::emitPow2CnsCnt;

void emitterStaticStats(FILE* fout)
void emitterStaticStats()
{
// The IG buffer size depends on whether we are storing a debug info pointer or not. For our purposes
// here, do not include that.
Expand All @@ -227,6 +227,8 @@ void emitterStaticStats(FILE* fout)

insGroup* igDummy = nullptr;

FILE* fout = jitstdout();

fprintf(fout, "\n");
fprintf(fout, "insGroup:\n");
fprintf(fout, "Offset / size of igNext = %3zu / %2zu\n", offsetof(insGroup, igNext),
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ int logf(const char* fmt, ...)
{
// if the EE refuses to log it, we try to send it to stdout
va_start(args, fmt);
written = vflogf(jitstdout, fmt, args);
written = vflogf(jitstdout(), fmt, args);
va_end(args);
}
#if 0 // Enable this only when you need it
Expand Down Expand Up @@ -431,7 +431,7 @@ void gcDump_logf(const char* fmt, ...)
{
// if the EE refuses to log it, we try to send it to stdout
va_start(args, fmt);
vflogf(jitstdout, fmt, args);
vflogf(jitstdout(), fmt, args);
va_end(args);
}
#if 0 // Enable this only when you need it
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/fgdiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ FILE* Compiler::fgOpenFlowGraphFile(bool* wbDontClose, Phases phase, PhasePositi
}
else if (strcmp(filename, "stdout") == 0)
{
fgxFile = jitstdout;
fgxFile = jitstdout();
*wbDontClose = true;
}
else if (strcmp(filename, "stderr") == 0)
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,10 +481,12 @@ void GenTree::ReportOperBashing(FILE* f)

#if MEASURE_NODE_SIZE

void GenTree::DumpNodeSizes(FILE* fp)
void GenTree::DumpNodeSizes()
{
// Dump the sizes of the various GenTree flavors

FILE* fp = jitstdout();

fprintf(fp, "Small tree node size = %zu bytes\n", TREE_NODE_SZ_SMALL);
fprintf(fp, "Large tree node size = %zu bytes\n", TREE_NODE_SZ_LARGE);
fprintf(fp, "\n");
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -2311,7 +2311,7 @@ struct GenTree
void SetIndirExceptionFlags(Compiler* comp);

#if MEASURE_NODE_SIZE
static void DumpNodeSizes(FILE* fp);
static void DumpNodeSizes();
#endif

#ifdef DEBUG
Expand Down
5 changes: 3 additions & 2 deletions src/coreclr/jit/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

/*****************************************************************************/

void jitprintf(const char* fmt, ...);

#ifdef DEBUG

#undef printf
Expand Down Expand Up @@ -44,7 +46,6 @@ extern "C" void ANALYZER_NORETURN __cdecl assertAbort(const char* why, const cha
// Re-define printf in Release to use jitstdout (can be overwritten with DOTNET_JitStdOutFile=file)
#undef printf
#define printf jitprintf
void jitprintf(const char* fmt, ...);

#undef assert
#define assert(p) (void)0
Expand All @@ -55,7 +56,7 @@ void jitprintf(const char* fmt, ...);
#define _HOST_H_
/*****************************************************************************/

extern FILE* jitstdout;
FILE* jitstdout();

inline FILE* procstdout()
{
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/inline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ void InlineContext::DumpData(unsigned indent)
{
const char* inlineReason = InlGetObservationString(m_Observation);
printf("%*s%u,\"%s\",\"%s\",", indent, "", GetOrdinal(), inlineReason, calleeName);
m_Policy->DumpData(jitstdout);
m_Policy->DumpData(jitstdout());
printf("\n");
}

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1421,7 +1421,7 @@ PhaseStatus LinearScan::doLinearScan()
#endif
)
{
dumpLsraStats(jitstdout);
dumpLsraStats(jitstdout());
}
#endif // TRACK_LSRA_STATS

Expand Down

0 comments on commit 5ba46f0

Please sign in to comment.