Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
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
29 changes: 15 additions & 14 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ void Compiler::JitLogEE(unsigned level, const char* fmt, ...)
if (verbose)
{
va_start(args, fmt);
vflogf(jitstdout, fmt, args);
vflogf(jitstdout(), fmt, args);
va_end(args);
}

Expand Down Expand Up @@ -1229,13 +1229,14 @@ void DisplayNowayAssertMap()
fout = _wfopen(strJitMeasureNowayAssertFile, W("a"));
if (fout == nullptr)
{
fprintf(jitstdout, "Failed to open JitMeasureNowayAssertFile \"%ws\"\n", strJitMeasureNowayAssertFile);
fprintf(jitstdout(), "Failed to open JitMeasureNowayAssertFile \"%ws\"\n",
strJitMeasureNowayAssertFile);
return;
}
}
else
{
fout = jitstdout;
fout = jitstdout();
}

// Iterate noway assert map, create sorted table by occurrence, dump it.
Expand All @@ -1252,7 +1253,7 @@ void DisplayNowayAssertMap()

jitstd::sort(nacp, nacp + count, NowayAssertCountMap::compare());

if (fout == jitstdout)
if (fout == jitstdout())
{
// Don't output the header if writing to a file, since we'll be appending to existing dumps in that case.
fprintf(fout, "\nnoway_assert counts:\n");
Expand All @@ -1265,7 +1266,7 @@ void DisplayNowayAssertMap()
nacp[i].fl.m_condStr);
}

if (fout != jitstdout)
if (fout != jitstdout())
{
fclose(fout);
fout = nullptr;
Expand Down Expand Up @@ -1330,7 +1331,7 @@ void Compiler::compStartup()
// Static vars of ValueNumStore
ValueNumStore::ValidateValueNumStoreStatics();

compDisplayStaticSizes(jitstdout);
compDisplayStaticSizes(jitstdout());
}

/*****************************************************************************
Expand Down Expand Up @@ -1388,11 +1389,11 @@ void Compiler::compShutdown()
#endif

#if NODEBASH_STATS
GenTree::ReportOperBashing(jitstdout);
GenTree::ReportOperBashing(jitstdout());
#endif

// Where should we write our statistics output?
FILE* fout = jitstdout;
FILE* fout = jitstdout();

#ifdef FEATURE_JIT_METHOD_PERF
if (compJitTimeLogFilename != nullptr)
Expand Down Expand Up @@ -1661,10 +1662,10 @@ void Compiler::compShutdown()
if (s_dspMemStats)
{
fprintf(fout, "\nAll allocations:\n");
ArenaAllocator::dumpAggregateMemStats(jitstdout);
ArenaAllocator::dumpAggregateMemStats(jitstdout());

fprintf(fout, "\nLargest method:\n");
ArenaAllocator::dumpMaxMemStats(jitstdout);
ArenaAllocator::dumpMaxMemStats(jitstdout());

fprintf(fout, "\n");
fprintf(fout, "---------------------------------------------------\n");
Expand All @@ -1684,7 +1685,7 @@ void Compiler::compShutdown()
if (JitConfig.DisplayLoopHoistStats() != 0)
#endif // DEBUG
{
PrintAggregateLoopHoistStats(jitstdout);
PrintAggregateLoopHoistStats(jitstdout());
}
#endif // LOOP_HOIST_STATS

Expand Down Expand Up @@ -5149,7 +5150,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
#if TRACK_LSRA_STATS
if (JitConfig.DisplayLsraStats() == 2)
{
m_pLinearScan->dumpLsraStatsCsv(jitstdout);
m_pLinearScan->dumpLsraStatsCsv(jitstdout());
}
#endif // TRACK_LSRA_STATS

Expand Down Expand Up @@ -5875,7 +5876,7 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr,
}
#endif // FUNC_INFO_LOGGING

// if (s_compMethodsCount==0) setvbuf(jitstdout, NULL, _IONBF, 0);
// if (s_compMethodsCount==0) setvbuf(jitstdout(), NULL, _IONBF, 0);

if (compIsForInlining())
{
Expand Down Expand Up @@ -6359,7 +6360,7 @@ void Compiler::compCompileFinish()
if (s_dspMemStats || verbose)
{
printf("\nAllocations for %s (MethodHash=%08x)\n", info.compFullName, info.compMethodHash());
compArenaAllocator->dumpMemStats(jitstdout);
compArenaAllocator->dumpMemStats(jitstdout());
}
#endif // DEBUG
#endif // MEASURE_MEM_ALLOC
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
61 changes: 43 additions & 18 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* 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,40 +96,58 @@ 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;
}

FILE* jitstdout()
{
if (s_jitstdout != nullptr)
Copy link
Member

Choose a reason for hiding this comment

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

s_jitstdout needs to be volatile for this to work reliably. Otherwise, the C++ compiler can compile this as:

var temp = s_jitstdout;
if (s_jitstdout != null)
    return temp;
...

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, I see. Addressed

{
return s_jitstdout;
}

return jitstdoutInit();
}

#ifndef DEBUG
void jitprintf(const char* fmt, ...)
{
va_list vl;
va_start(vl, fmt);
vfprintf(jitstdout, fmt, vl);
vfprintf(jitstdout(), fmt, vl);
va_end(vl);
}
#endif
Expand All @@ -136,14 +161,14 @@ void jitShutdown(bool processIsTerminating)

Compiler::compShutdown();

if (jitstdout != procstdout())
if ((s_jitstdout != nullptr) && (s_jitstdout != 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(s_jitstdout);
}
}

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
2 changes: 1 addition & 1 deletion src/coreclr/jit/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,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