return (m_dwFlags & IGNORE_UNHANDLED_EXCEPTIONS);
}
- void SetPassiveDomain()
- {
- LIMITED_METHOD_CONTRACT;
-
- m_dwFlags |= PASSIVE_DOMAIN;
- }
-
BOOL IsPassiveDomain()
{
LIMITED_METHOD_CONTRACT;
return (m_dwFlags & PASSIVE_DOMAIN);
}
- void SetVerificationDomain()
- {
- LIMITED_METHOD_CONTRACT;
-
- m_dwFlags |= VERIFICATION_DOMAIN;
- }
-
- BOOL IsVerificationDomain()
- {
- LIMITED_METHOD_CONTRACT;
-
- return (m_dwFlags & VERIFICATION_DOMAIN);
- }
-
- void SetIllegalVerificationDomain()
- {
- LIMITED_METHOD_CONTRACT;
-
- m_dwFlags |= ILLEGAL_VERIFICATION_DOMAIN;
- }
-
- BOOL IsIllegalVerificationDomain()
- {
- LIMITED_METHOD_CONTRACT;
-
- return (m_dwFlags & ILLEGAL_VERIFICATION_DOMAIN);
- }
-
void SetCompilationDomain()
{
LIMITED_METHOD_CONTRACT;
return dac_cast<PTR_CompilationDomain>(this);
}
- void SetRemotingConfigured()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- FastInterlockOr((ULONG*)&m_dwFlags, REMOTING_CONFIGURED_FOR_DOMAIN);
- }
-
- BOOL IsRemotingConfigured()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return m_dwFlags & REMOTING_CONFIGURED_FOR_DOMAIN;
- }
-
- void SetOrphanedLocks()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- FastInterlockOr((ULONG*)&m_dwFlags, ORPHANED_LOCKS);
- }
-
- BOOL HasOrphanedLocks()
- {
- LIMITED_METHOD_CONTRACT;
- STATIC_CONTRACT_SO_TOLERANT;
- return m_dwFlags & ORPHANED_LOCKS;
- }
-
static void ExceptionUnwind(Frame *pFrame);
#ifdef _DEBUG
USER_CREATED_DOMAIN = 0x0002, // created by call to AppDomain.CreateDomain
ALLOCATEDCOM = 0x0008,
LOAD_SYSTEM_ASSEMBLY_EVENT_SENT = 0x0040,
- REMOTING_CONFIGURED_FOR_DOMAIN = 0x0100,
COMPILATION_DOMAIN = 0x0400, // Are we ngenning?
- ORPHANED_LOCKS = 0x1000, // Orphaned locks exist in this appdomain.
PASSIVE_DOMAIN = 0x2000, // Can we execute code in this AppDomain
- VERIFICATION_DOMAIN = 0x4000, // This is a verification domain
- ILLEGAL_VERIFICATION_DOMAIN = 0x8000, // This can't be a verification domain
IGNORE_UNHANDLED_EXCEPTIONS = 0x10000, // AppDomain was created using the APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS flag
ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP = 0x20000, // AppDomain was created using the APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP flag
ENABLE_SKIP_PLAT_CHECKS = 0x200000, // Skip various assembly checks (like platform check)
if (gc.requestingAssembly == NULL)
{
pRefAssembly = SystemDomain::GetCallersAssembly(stackMark);
-
- // Cross-appdomain callers aren't allowed as the parent
- if (pRefAssembly &&
- (pRefAssembly->GetDomain() != pThread->GetDomain()))
- {
- pRefAssembly = NULL;
- }
}
else
+ {
pRefAssembly = gc.requestingAssembly->GetAssembly();
+ }
// Shared or collectible assemblies should not be used for the parent in the
// late-bound case.
#endif // FEATURE_COMINTEROP
}
- if (GetAssembly()->IsDomainNeutral() && !IsSingleAppDomain())
- {
- m_ModuleIndex = Module::AllocateModuleIndex();
- m_ModuleID = (DomainLocalModule*)Module::IndexToID(m_ModuleIndex);
- }
- else
- {
- // this will be initialized a bit later.
- m_ModuleID = NULL;
- m_ModuleIndex.m_dwIndex = (SIZE_T)-1;
- }
+ // this will be initialized a bit later.
+ m_ModuleID = NULL;
+ m_ModuleIndex.m_dwIndex = (SIZE_T)-1;
#ifdef FEATURE_COLLECTIBLE_TYPES
if (GetAssembly()->IsCollectible())
}
else
{
-
- CONSISTENCY_CHECK(dac_cast<TADDR>(pDomain) == dac_cast<TADDR>(GetDomain()) || IsSingleAppDomain());
RETURN dac_cast<PTR_DomainFile>(m_ModuleID->GetDomainFile());
}
}
}
else
{
- if (dac_cast<TADDR>(pDomain) == dac_cast<TADDR>(GetDomain()) || IsSingleAppDomain())
- RETURN m_ModuleID->GetDomainFile();
- else
- RETURN NULL;
+ RETURN m_ModuleID->GetDomainFile();
}
}
DomainLocalModule* pModuleData = 0;
// Do we need to allocate memory for the non GC statics?
- if ((GetAssembly()->IsDomainNeutral() && !IsSingleAppDomain())|| m_ModuleID == NULL)
+ if (m_ModuleID == NULL)
{
// Allocate memory for the module statics.
LoaderAllocator *pLoaderAllocator = NULL;
// Verify that the space is really zero initialized
_ASSERTE(pModuleData->GetPrecomputedGCStaticsBasePointer() == NULL);
- // Make sure that the newly allocated DomainLocalModule gets
- // a copy of the domain-neutral module ID.
- if (GetAssembly()->IsDomainNeutral() && !IsSingleAppDomain())
- {
- // If the module was loaded as domain-neutral, we can find the ID by
- // casting 'm_ModuleID'.
-
- _ASSERTE(Module::IDToIndex((SIZE_T)m_ModuleID) == this->m_ModuleIndex);
- pModuleData->m_ModuleIndex = Module::IDToIndex((SIZE_T)m_ModuleID);
-
- // Eventually I want to just do this instead...
- //pModuleData->m_ModuleIndex = this->m_ModuleIndex;
- }
- else
- {
- // If the module was loaded as domain-specific, then we need to assign
- // this module a domain-neutral module ID.
- pModuleData->m_ModuleIndex = Module::AllocateModuleIndex();
- m_ModuleIndex = pModuleData->m_ModuleIndex;
- }
+ // If the module was loaded as domain-specific, then we need to assign
+ // this module a domain-neutral module ID.
+ pModuleData->m_ModuleIndex = Module::AllocateModuleIndex();
+ m_ModuleIndex = pModuleData->m_ModuleIndex;
}
else
{
LOG((LF_CLASSLOADER, LL_INFO10, "STATICS: Allocation not needed for ngened non shared module %s in Appdomain %08x\n"));
}
- if (GetAssembly()->IsDomainNeutral() && !IsSingleAppDomain())
+ // Non shared case, module points directly to the statics. In ngen case
+ // m_pDomainModule is already set for the non shared case
+ if (m_ModuleID == NULL)
{
- DomainLocalBlock *pLocalBlock;
- {
- pLocalBlock = pDomainFile->GetAppDomain()->GetDomainLocalBlock();
- pLocalBlock->SetModuleSlot(GetModuleIndex(), pModuleData);
- }
-
- pLocalBlock->SetDomainFile(GetModuleIndex(), pDomainFile);
+ m_ModuleID = pModuleData;
}
- else
- {
- // Non shared case, module points directly to the statics. In ngen case
- // m_pDomainModule is already set for the non shared case
- if (m_ModuleID == NULL)
- {
- m_ModuleID = pModuleData;
- }
- m_ModuleID->SetDomainFile(pDomainFile);
- }
+ m_ModuleID->SetDomainFile(pDomainFile);
// Allocate static handles now.
// NOTE: Bootstrapping issue with mscorlib - we will manually allocate later
const BYTE *m_pArgs; // pointer to first unfixed unmanaged arg
};
-inline bool IsSingleAppDomain()
-{
- // CoreCLR always runs as single AppDomain
- return true;
-}
-
#endif // !CEELOAD_H_
g_pOverlappedDataClass = MscorlibBinder::GetClass(CLASS__OVERLAPPEDDATA);
// We have optimization to avoid creating event if IO is in default domain. This depends on default domain
// can not be unloaded.
- _ASSERTE(IsSingleAppDomain());
_ASSERTE(SystemDomain::System()->DefaultDomain()->GetId().m_dwId == DefaultADID);
}
bool fNeedsNonTrivialHelper = false;
- if (pMT->IsDomainNeutral() && !IsSingleAppDomain())
- {
- fNeedsNonTrivialHelper = true;
- }
- else
if (pMT->Collectible() && (kind != ENCODE_CCTOR_TRIGGER))
{
// Collectible statics are not pinned - the fast getters expect statics to be pinned
AppDomain *pReturnDomain = pReturnContext->GetDomain();
AppDomain* pCurrentDomain = m_pDomain;
- bool fChangedDomains = m_pDomain != pReturnDomain;
-
- if (fChangedDomains)
- {
- if (HasLockInCurrentDomain())
- {
- if (GetAppDomain()->IsDefaultDomain() || // We should never orphan a lock in default domain.
- !IsRudeAbort()) // If rudeabort, managed backout may not be run.
- {
- // One would like to assert that this case never occurs, but
- // a rude abort can easily leave unreachable locked objects,
- // which we have to allow.
- STRESS_LOG2(LF_SYNC, LL_INFO1000, "Locks are orphaned while exiting a domain (enter: %d, exit: %d)\n", m_dwBeginLockCount, m_dwLockCount);
-#ifdef _DEBUG
- STRESS_LOG0 (LF_APPDOMAIN, LL_INFO10, "Thread::ReturnToContext Lock not released\n");
-#endif
- }
-
- AppDomain *pFromDomain = GetAppDomain();
-
- // There is a race when EE Thread for a new thread is allocated in the place of the old EE Thread.
- // The lock accounting will get confused if there are orphaned locks. Set the flag that allows us to relax few asserts.
- SetThreadStateNC(TSNC_UnbalancedLocks);
- pFromDomain->SetOrphanedLocks();
-
- if (!pFromDomain->IsDefaultDomain())
- {
- // If a Thread orphaned a lock, we don't want a host to recycle the Thread object,
- // since the lock count is reset when the thread leaves this domain.
- SetThreadStateNC(TSNC_CannotRecycle);
- }
-
- // It is a disaster if a lock leaks in default domain. We can never unload default domain.
- // _ASSERTE (!pFromDomain->IsDefaultDomain());
- EPolicyAction action = GetEEPolicy()->GetActionOnFailure(FAIL_OrphanedLock);
- switch (action)
- {
- case eExitProcess:
- case eFastExitProcess:
- case eRudeExitProcess:
- case eDisableRuntime:
- GetEEPolicy()->HandleExitProcessFromEscalation(action,HOST_E_EXITPROCESS_ADUNLOAD);
- break;
- default:
- break;
- }
- }
-
- m_dwLockCount = m_dwBeginLockCount;
- m_dwBeginLockCount = pFrame->GetLockCount();
-
- }
-
if (m_Context == pReturnContext)
{
- _ASSERTE(m_Context->GetDomain() == pReturnContext->GetDomain());
return;
}
m_Context = pReturnContext;
- if (fChangedDomains)
- {
- STRESS_LOG2(LF_APPDOMAIN, LL_INFO100000, "Returning from %d to %d\n", pADOnStack.m_dwId, pReturnContext->GetDomain()->GetId().m_dwId);
-
- _ASSERTE(pADOnStack == m_pDomain->GetId());
-
- _ASSERTE(pFrame);
- //_ASSERTE(!fLinkFrame || pThread->GetFrame() == pFrame);
-
- FlushIBCInfo();
-
- m_pDomain = pReturnDomain;
- SetAppDomain(pReturnDomain);
-
- // Restore the last thrown object to what it was before the AD transition. Note that if
- // an exception was thrown out of the AD we transitionned into, it will be raised in
- // RaiseCrossContextException and the EH system will store it as the last thrown
- // object if it gets handled by an EX_CATCH.
- SafeSetLastThrownObject(pFrame->GetLastThrownObjectInParentContext());
- }
-
pFrame->Pop();
- if (fChangedDomains)
- {
-
- // Do this last so that thread is not labeled as out of the domain until all cleanup is done.
- ADID adid=pCurrentDomain->GetId();
- pCurrentDomain->ThreadExit(this, pFrame);
-
-#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
- if (g_fEnableARM)
- {
- // Update the old AppDomain's count of processor usage by threads executing within it.
- pCurrentDomain->UpdateProcessorUsage(QueryThreadProcessorUsage());
- FireEtwThreadDomainEnter((ULONGLONG)this, (ULONGLONG)pReturnDomain, GetClrInstanceId());
- }
-#endif // FEATURE_APPDOMAIN_RESOURCE_MONITORING
- }
-
- if (fChangedDomains && IsAbortRequested() && HasLockInCurrentDomain())
- {
- EPolicyAction action = GetEEPolicy()->GetActionOnFailure(FAIL_CriticalResource);
- // It is a disaster if a lock leaks in default domain. We can never unload default domain.
- // _ASSERTE (action == eThrowException || !pReturnDomain->IsDefaultDomain());
- switch (action)
- {
- case eExitProcess:
- case eFastExitProcess:
- case eRudeExitProcess:
- case eDisableRuntime:
- GetEEPolicy()->HandleExitProcessFromEscalation(action,HOST_E_EXITPROCESS_ADUNLOAD);
- break;
- default:
- break;
- }
- }
-
#ifdef _DEBUG_ADUNLOAD
printf("Thread::ReturnToContext %x,%8.8x pop? %d current frame is %8.8x\n", GetThreadId(), this, 1, GetFrame());
#endif
return fct.pFrame;
}
-// Get outermost (oldest) AppDomain for this thread (not counting the default
-// domain every one starts in).
-AppDomain *Thread::GetInitialDomain()
-{
- CONTRACTL {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- AppDomain *pDomain = m_pDomain;
- AppDomain *pPrevDomain = NULL;
- Frame *pFrame = GetFrame();
- while (pFrame != FRAME_TOP)
- {
- if (pFrame->GetVTablePtr() == ContextTransitionFrame::GetMethodFrameVPtr())
- {
- if (pPrevDomain)
- pDomain = pPrevDomain;
- pPrevDomain = pFrame->GetReturnDomain();
- }
- pFrame = pFrame->Next();
- }
- return pDomain;
-}
-
BOOL Thread::HaveExtraWorkForFinalizer()
{
LIMITED_METHOD_CONTRACT;
{
_ASSERTE(flags == MTCSF_NormalBase);
- if(!IsSingleAppDomain())
- {
- // This assert shouldnt be hit in CoreCLR since:
- //
- // 1) It has no concept of managed entry point that is invoked by the shim. You can
- // only run managed code via hosting APIs that will run code in non-default domains.
- //
- // 2) Managed threads cannot be created in DefaultDomain since no user code executes
- // in default domain.
- //
- // So, if this is hit, something is not right!
- _ASSERTE(!"How come a managed thread in CoreCLR has suffered unhandled exception in DefaultDomain?");
- }
-
LOG((LF_EH, LL_INFO100, "ThreadBaseRedirectingFilter: setting TSNC_ProcessedUnhandledException\n"));
//
// The next time Thread A has an exception go unhandled, our UEF will see TSNC_ProcessedUnhandledException set and assume (incorrectly) UE processing has happened and
// will fail to honor the host policy (e.g. swallow unhandled exception). Thus, the 2nd unhandled exception may end up crashing the app when it should not.
//
- if (IsSingleAppDomain() && (ret != EXCEPTION_EXECUTE_HANDLER))
+ if (ret != EXCEPTION_EXECUTE_HANDLER)
{
// Since we have already done unhandled exception processing for it, we dont want it
// to happen again if our UEF gets invoked upon returning back to the OS.
{
LIMITED_METHOD_DAC_CONTRACT;
- // if another thread is asking about our thread, we could be in the middle of an AD transition so
- // the context and AD may not match if have set one but not the other. Can live without checking when
- // another thread is asking it as this method is mostly called on our own thread so will mostly get the
- // checking. If are int the middle of a transition, this could return either the old or the new AD.
- // But no matter what we do, such as lock on the transition, by the time are done could still have
- // changed right after we asked, so really no point.
-#ifdef _DEBUG_IMPL
- BEGIN_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
- if (!g_fEEShutDown && this == GetThread())
- {
- if (!fMidContextTransitionOK)
- {
- // We also want to suppress the "domain on context == domain on thread" check if this might
- // be called during a context or AD transition (in which case fMidContextTransitionOK is nonzero).
- // A profiler stackwalk can occur at arbitrary times, including during these transitions, but
- // the stackwalk is still safe to do at this point, so we don't want to trigger this assert.
- _ASSERTE((m_Context == NULL && m_pDomain == NULL) || m_Context->GetDomain() == m_pDomain);
- }
- AppDomain* valueInTLSSlot = GetAppDomain();
- _ASSERTE(valueInTLSSlot == 0 || valueInTLSSlot == m_pDomain);
- }
- END_GETTHREAD_ALLOWED_IN_NO_THROW_REGION;
-#endif
-
return m_pDomain;
}