Skip to content

Commit 2401fdf

Browse files
Copilotjkotas
andcommitted
Fold environmentnative into comutilnative and remove GetCurrentTime undef
Co-authored-by: jkotas <[email protected]>
1 parent ea9c753 commit 2401fdf

File tree

7 files changed

+210
-255
lines changed

7 files changed

+210
-255
lines changed

src/coreclr/vm/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ set(VM_SOURCES_WKS
320320
eecontract.cpp
321321
eepolicy.cpp
322322
eetoprofinterfaceimpl.cpp
323-
environmentnative.cpp
324323
eventpipeinternal.cpp
325324
fcall.cpp
326325
fieldmarshaler.cpp
@@ -436,7 +435,6 @@ set(VM_HEADERS_WKS
436435
eeprofinterfaces.inl
437436
eetoprofinterfaceimpl.h
438437
eetoprofinterfaceimpl.inl
439-
environmentnative.h
440438
eventpipeadapter.h
441439
eventpipeadaptertypes.h
442440
eventpipeinternal.h

src/coreclr/vm/comutilnative.cpp

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
#include "finalizerthread.h"
3535
#include "threadsuspend.h"
3636
#include <minipal/memorybarrierprocesswide.h>
37+
#include "string.h"
38+
#include "sstring.h"
39+
#include "array.h"
40+
#include "eepolicy.h"
41+
#include <minipal/cpuid.h>
3742

3843
#ifdef FEATURE_COMINTEROP
3944
#include "comcallablewrapper.h"
@@ -564,6 +569,183 @@ FCIMPL3(VOID, Buffer::BulkMoveWithWriteBarrier, void *dst, void *src, size_t byt
564569
}
565570
FCIMPLEND
566571

572+
//
573+
// EnvironmentNative
574+
//
575+
extern "C" VOID QCALLTYPE Environment_Exit(INT32 exitcode)
576+
{
577+
QCALL_CONTRACT;
578+
579+
BEGIN_QCALL;
580+
581+
// The exit code for the process is communicated in one of two ways. If the
582+
// entrypoint returns an 'int' we take that. Otherwise we take a latched
583+
// process exit code. This can be modified by the app via setting
584+
// Environment's ExitCode property.
585+
SetLatchedExitCode(exitcode);
586+
587+
ForceEEShutdown();
588+
589+
END_QCALL;
590+
}
591+
592+
FCIMPL1(VOID,EnvironmentNative::SetExitCode,INT32 exitcode)
593+
{
594+
FCALL_CONTRACT;
595+
596+
// The exit code for the process is communicated in one of two ways. If the
597+
// entrypoint returns an 'int' we take that. Otherwise we take a latched
598+
// process exit code. This can be modified by the app via setting
599+
// Environment's ExitCode property.
600+
SetLatchedExitCode(exitcode);
601+
}
602+
FCIMPLEND
603+
604+
FCIMPL0(INT32, EnvironmentNative::GetExitCode)
605+
{
606+
FCALL_CONTRACT;
607+
608+
// Return whatever has been latched so far. This is uninitialized to 0.
609+
return GetLatchedExitCode();
610+
}
611+
FCIMPLEND
612+
613+
extern "C" INT32 QCALLTYPE Environment_GetProcessorCount()
614+
{
615+
QCALL_CONTRACT;
616+
617+
INT32 processorCount = 0;
618+
619+
BEGIN_QCALL;
620+
621+
processorCount = GetCurrentProcessCpuCount();
622+
623+
END_QCALL;
624+
625+
return processorCount;
626+
}
627+
628+
struct FindFailFastCallerStruct {
629+
StackCrawlMark* pStackMark;
630+
UINT_PTR retAddress;
631+
};
632+
633+
// This method is called by the GetMethod function and will crawl backward
634+
// up the stack for integer methods.
635+
static StackWalkAction FindFailFastCallerCallback(CrawlFrame* frame, VOID* data) {
636+
CONTRACTL
637+
{
638+
NOTHROW;
639+
GC_NOTRIGGER;
640+
MODE_ANY;
641+
}
642+
CONTRACTL_END;
643+
644+
FindFailFastCallerStruct* pFindCaller = (FindFailFastCallerStruct*) data;
645+
646+
// The check here is between the address of a local variable
647+
// (the stack mark) and a pointer to the EIP for a frame
648+
// (which is actually the pointer to the return address to the
649+
// function from the previous frame). So we'll actually notice
650+
// which frame the stack mark was in one frame later. This is
651+
// fine since we only implement LookForMyCaller.
652+
_ASSERTE(*pFindCaller->pStackMark == LookForMyCaller);
653+
if (!frame->IsInCalleesFrames(pFindCaller->pStackMark))
654+
return SWA_CONTINUE;
655+
656+
pFindCaller->retAddress = GetControlPC(frame->GetRegisterSet());
657+
return SWA_ABORT;
658+
}
659+
660+
static thread_local int8_t alreadyFailing = 0;
661+
662+
extern "C" void QCALLTYPE Environment_FailFast(QCall::StackCrawlMarkHandle mark, PCWSTR message, QCall::ObjectHandleOnStack exception, PCWSTR errorSource)
663+
{
664+
QCALL_CONTRACT;
665+
666+
BEGIN_QCALL;
667+
668+
GCX_COOP();
669+
670+
FindFailFastCallerStruct findCallerData;
671+
findCallerData.pStackMark = mark;
672+
findCallerData.retAddress = 0;
673+
GetThread()->StackWalkFrames(FindFailFastCallerCallback, &findCallerData, FUNCTIONSONLY | QUICKUNWIND);
674+
675+
if (message == NULL || message[0] == W('\0'))
676+
{
677+
OutputDebugString(W("CLR: Managed code called FailFast without specifying a reason.\r\n"));
678+
}
679+
else
680+
{
681+
OutputDebugString(W("CLR: Managed code called FailFast.\r\n"));
682+
OutputDebugString(message);
683+
OutputDebugString(W("\r\n"));
684+
}
685+
686+
LPCWSTR argExceptionString = NULL;
687+
StackSString msg;
688+
// Because Environment_FailFast should kill the process, any subsequent calls are likely nested call from managed while formatting the exception message or the stack trace.
689+
// Only collect exception string if this is the first attempt to fail fast on this thread.
690+
alreadyFailing++;
691+
if (alreadyFailing != 1)
692+
{
693+
argExceptionString = W("Environment.FailFast called recursively.");
694+
}
695+
else if (exception.Get() != NULL)
696+
{
697+
GetExceptionMessage(exception.Get(), msg);
698+
argExceptionString = msg.GetUnicode();
699+
}
700+
701+
Thread *pThread = GetThread();
702+
703+
#ifndef TARGET_UNIX
704+
// If we have the exception object, then try to setup
705+
// the watson bucket if it has any details.
706+
// On CoreCLR, Watson may not be enabled. Thus, we should
707+
// skip this, if required.
708+
if (IsWatsonEnabled())
709+
{
710+
if ((exception.Get() == NULL) || !SetupWatsonBucketsForFailFast((EXCEPTIONREF)exception.Get()))
711+
{
712+
PTR_EHWatsonBucketTracker pUEWatsonBucketTracker = pThread->GetExceptionState()->GetUEWatsonBucketTracker();
713+
_ASSERTE(pUEWatsonBucketTracker != NULL);
714+
pUEWatsonBucketTracker->SaveIpForWatsonBucket(findCallerData.retAddress);
715+
pUEWatsonBucketTracker->CaptureUnhandledInfoForWatson(TypeOfReportedError::FatalError, pThread, NULL);
716+
if (pUEWatsonBucketTracker->RetrieveWatsonBuckets() == NULL)
717+
{
718+
pUEWatsonBucketTracker->ClearWatsonBucketDetails();
719+
}
720+
}
721+
}
722+
#endif // !TARGET_UNIX
723+
724+
// stash the user-provided exception object. this will be used as
725+
// the inner exception object to the FatalExecutionEngineException.
726+
if (exception.Get() != NULL)
727+
pThread->SetLastThrownObject(exception.Get());
728+
729+
EEPolicy::HandleFatalError(COR_E_FAILFAST, findCallerData.retAddress, message, NULL, errorSource, argExceptionString);
730+
731+
END_QCALL;
732+
}
733+
734+
#if defined(TARGET_X86) || defined(TARGET_AMD64)
735+
736+
extern "C" void QCALLTYPE X86BaseCpuId(int cpuInfo[4], int functionId, int subFunctionId)
737+
{
738+
QCALL_CONTRACT;
739+
740+
BEGIN_QCALL;
741+
742+
__cpuidex(cpuInfo, functionId, subFunctionId);
743+
744+
END_QCALL;
745+
}
746+
747+
#endif // defined(TARGET_X86) || defined(TARGET_AMD64)
748+
567749
//
568750
// ObjectNative
569751
//

src/coreclr/vm/comutilnative.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include "qcall.h"
2525
#include "windows.h"
2626
#include "gchelpersnative.h"
27-
#undef GetCurrentTime
2827

2928
//
3029
//
@@ -91,6 +90,34 @@ class Buffer
9190
extern "C" void QCALLTYPE Buffer_Clear(void *dst, size_t length);
9291
extern "C" void QCALLTYPE Buffer_MemMove(void *dst, void *src, size_t length);
9392

93+
//
94+
// EnvironmentNative
95+
//
96+
class EnvironmentNative
97+
{
98+
public:
99+
// Functions on the System.Environment class
100+
static FCDECL1(VOID,SetExitCode,INT32 exitcode);
101+
static FCDECL0(INT32, GetExitCode);
102+
};
103+
104+
extern "C" void QCALLTYPE Environment_Exit(INT32 exitcode);
105+
106+
extern "C" void QCALLTYPE Environment_FailFast(QCall::StackCrawlMarkHandle mark, PCWSTR message, QCall::ObjectHandleOnStack exception, PCWSTR errorSource);
107+
108+
// Returns the number of logical processors that can be used by managed code
109+
extern "C" INT32 QCALLTYPE Environment_GetProcessorCount();
110+
111+
#if defined(TARGET_X86) || defined(TARGET_AMD64)
112+
extern "C" void QCALLTYPE X86BaseCpuId(int cpuInfo[4], int functionId, int subFunctionId);
113+
#endif // defined(TARGET_X86) || defined(TARGET_AMD64)
114+
115+
extern "C" void QCALLTYPE GetTypeLoadExceptionMessage(UINT32 resId, QCall::StringHandleOnStack retString);
116+
117+
extern "C" void QCALLTYPE GetFileLoadExceptionMessage(UINT32 hr, QCall::StringHandleOnStack retString);
118+
119+
extern "C" void QCALLTYPE FileLoadException_GetMessageForHR(UINT32 hresult, QCall::StringHandleOnStack retString);
120+
94121
//
95122
// Object
96123
//

src/coreclr/vm/corelib.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "commodule.h"
2424
#include "marshalnative.h"
2525
#include "nativelibrarynative.h"
26-
#include "environmentnative.h"
2726
#include "comutilnative.h"
2827
#include "comsynchronizable.h"
2928
#include "floatdouble.h"

0 commit comments

Comments
 (0)