diff options
author | antofik <antofik@gmail.com> | 2018-01-22 05:03:51 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-01-21 18:03:51 -0800 |
commit | 59714b683f40fac869050ca08acc5503e84dc776 (patch) | |
tree | 1512f4562d579977288002abb6432b32a2df2e8f | |
parent | 3bd16103e76fbad8de7a37cb37f6a6f74ce46dfd (diff) | |
download | coreclr-59714b683f40fac869050ca08acc5503e84dc776.tar.gz coreclr-59714b683f40fac869050ca08acc5503e84dc776.tar.bz2 coreclr-59714b683f40fac869050ca08acc5503e84dc776.zip |
Remove AppDomainLeaks configuration option (#15956)
Removed all usages of AppDomainLeaks configuration option and
CHECK_APP_DOMAIN_LEAKS feature
Fix #12094
35 files changed, 14 insertions, 1720 deletions
diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h index 138251cb2e..afd3db3fe4 100644 --- a/src/gc/gcinterface.h +++ b/src/gc/gcinterface.h @@ -844,11 +844,11 @@ struct ScanContext uintptr_t stack_limit; // Lowest point on the thread stack that the scanning logic is permitted to read bool promotion; //TRUE: Promotion, FALSE: Relocation. bool concurrent; //TRUE: concurrent scanning -#if CHECK_APP_DOMAIN_LEAKS || defined (FEATURE_APPDOMAIN_RESOURCE_MONITORING) || defined (DACCESS_COMPILE) +#if defined (FEATURE_APPDOMAIN_RESOURCE_MONITORING) || defined (DACCESS_COMPILE) AppDomain *pCurrentDomain; #else void* _unused1; -#endif //CHECK_APP_DOMAIN_LEAKS || FEATURE_APPDOMAIN_RESOURCE_MONITORING || DACCESS_COMPILE +#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING || DACCESS_COMPILE #if defined(GC_PROFILING) || defined (DACCESS_COMPILE) MethodDesc *pMD; diff --git a/src/gc/handletable.cpp b/src/gc/handletable.cpp index 48b763d9e8..416363c7bc 100644 --- a/src/gc/handletable.cpp +++ b/src/gc/handletable.cpp @@ -368,15 +368,6 @@ void ValidateFetchObjrefForHandle(OBJECTREF objref, ADIndex appDomainIndex) _ASSERTE(pDomain != NULL); _ASSERTE(!pDomain->NoAccessToHandleTable()); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks() && objref != NULL) - { - if (appDomainIndex.m_dwIndex) - objref->TryAssignAppDomain(pDomain); - else - objref->TrySetAppDomainAgile(); - } -#endif END_DEBUG_ONLY_CODE; } @@ -398,15 +389,6 @@ void ValidateAssignObjrefForHandle(OBJECTREF objref, ADIndex appDomainIndex) _ASSERTE(pDomain != NULL); _ASSERTE(!pDomain->NoAccessToHandleTable()); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks() && objref != NULL) - { - if (appDomainIndex.m_dwIndex) - objref->TryAssignAppDomain(pDomain); - else - objref->TrySetAppDomainAgile(); - } -#endif END_DEBUG_ONLY_CODE; } diff --git a/src/inc/eetwain.h b/src/inc/eetwain.h index 497e0b0e6b..97a742b576 100644 --- a/src/inc/eetwain.h +++ b/src/inc/eetwain.h @@ -40,11 +40,7 @@ #define HAS_QUICKUNWIND #endif -#if CHECK_APP_DOMAIN_LEAKS -#define CHECK_APP_DOMAIN GC_CALL_CHECK_APP_DOMAIN -#else #define CHECK_APP_DOMAIN 0 -#endif #define NO_OVERRIDE_OFFSET (DWORD)-1 diff --git a/src/strongname/api/common.h b/src/strongname/api/common.h index 7cea2ec795..d3d0d2faf5 100644 --- a/src/strongname/api/common.h +++ b/src/strongname/api/common.h @@ -246,11 +246,6 @@ inline void* memcpyUnsafe(void *dest, const void *src, size_t len) extern "C" void * __cdecl GCSafeMemCpy(void *, const void *, size_t); #define memcpy(dest, src, len) GCSafeMemCpy(dest, src, len) #endif // !defined(memcpy) - - - #if !defined(CHECK_APP_DOMAIN_LEAKS) - #define CHECK_APP_DOMAIN_LEAKS 1 - #endif #else // !_DEBUG && !DACCESS_COMPILE && !CROSSGEN_COMPILE inline void* memcpyNoGCRefs(void * dest, const void * src, size_t len) { WRAPPER_NO_CONTRACT; diff --git a/src/vm/amd64/JitHelpers_Fast.asm b/src/vm/amd64/JitHelpers_Fast.asm index 5e0d79f74f..6b94c66782 100644 --- a/src/vm/amd64/JitHelpers_Fast.asm +++ b/src/vm/amd64/JitHelpers_Fast.asm @@ -754,22 +754,6 @@ LEAF_ENTRY JIT_Stelem_Ref, _TEXT test r8, r8 jz AssigningNull -ifdef CHECK_APP_DOMAIN_LEAKS - ; get Array TypeHandle - mov r9, [r10 + OFFSETOF__MethodTable__m_ElementType] ; 10h -> typehandle offset - ; check for non-MT - test r9, 2 - jnz NoCheck - - ; Check VMflags of element type - mov r9, [r9 + OFFSETOF__MethodTable__m_pEEClass] - mov r9d, dword ptr [r9 + OFFSETOF__EEClass__m_wAuxFlags] - test r9d, EEClassFlags - jnz ArrayStoreCheck_Helper - - NoCheck: -endif - mov r9, [r10 + OFFSETOF__MethodTable__m_ElementType] ; 10h -> typehandle offset ; check for exact match diff --git a/src/vm/amd64/jithelpers_fast.S b/src/vm/amd64/jithelpers_fast.S index 0ec63f7c5c..63b54297a6 100644 --- a/src/vm/amd64/jithelpers_fast.S +++ b/src/vm/amd64/jithelpers_fast.S @@ -410,22 +410,6 @@ LEAF_ENTRY JIT_Stelem_Ref, _TEXT test rdx, rdx jz LOCAL_LABEL(AssigningNull) -#ifdef CHECK_APP_DOMAIN_LEAKS - // get Array TypeHandle - mov rcx, [r10 + OFFSETOF__MethodTable__m_ElementType] // 10h -> typehandle offset, - // check for non-MT - test rcx, 2 - jnz LOCAL_LABEL(NoCheck) - - // Check VMflags of element type - mov rcx, [rcx + OFFSETOF__MethodTable__m_pEEClass] - mov ecx, dword ptr [rcx + OFFSETOF__EEClass__m_wAuxFlags] - test ecx, EEClassFlags - jnz C_FUNC(ArrayStoreCheck_Helper) - - LOCAL_LABEL(NoCheck): -#endif - mov rcx, [r10 + OFFSETOF__MethodTable__m_ElementType] // 10h -> typehandle offset // check for exact match diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index bab3f65c02..96fd088c03 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -2292,9 +2292,6 @@ void SystemDomain::PreallocateSpecialObjects() _ASSERTE(g_pPreallocatedSentinelObject == NULL); OBJECTREF pPreallocatedSentinalObject = AllocateObject(g_pObjectClass); -#if CHECK_APP_DOMAIN_LEAKS - pPreallocatedSentinalObject->SetSyncBlockAppDomainAgile(); -#endif g_pPreallocatedSentinelObject = CreatePinningHandle( pPreallocatedSentinalObject ); #ifdef FEATURE_PREJIT @@ -2346,9 +2343,6 @@ void SystemDomain::CreatePreallocatedExceptions() EXCEPTIONREF pRudeAbortException = (EXCEPTIONREF)AllocateObject(g_pThreadAbortExceptionClass); -#if CHECK_APP_DOMAIN_LEAKS - pRudeAbortException->SetSyncBlockAppDomainAgile(); -#endif pRudeAbortException->SetHResult(COR_E_THREADABORTED); pRudeAbortException->SetXCode(EXCEPTION_COMPLUS); _ASSERTE(g_pPreallocatedRudeThreadAbortException == NULL); @@ -2356,9 +2350,6 @@ void SystemDomain::CreatePreallocatedExceptions() EXCEPTIONREF pAbortException = (EXCEPTIONREF)AllocateObject(g_pThreadAbortExceptionClass); -#if CHECK_APP_DOMAIN_LEAKS - pAbortException->SetSyncBlockAppDomainAgile(); -#endif pAbortException->SetHResult(COR_E_THREADABORTED); pAbortException->SetXCode(EXCEPTION_COMPLUS); _ASSERTE(g_pPreallocatedThreadAbortException == NULL); @@ -8200,12 +8191,6 @@ void AppDomain::Close() LOG((LF_APPDOMAIN | LF_CORDB, LL_INFO10, "AppDomain::Domain [%d] %#08x %ls is collected.\n", GetId().m_dwId, this, GetFriendlyNameForLogging())); - -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - // at this point shouldn't have any non-agile objects in the heap because we finalized all the non-agile ones. - SyncBlockCache::GetSyncBlockCache()->CheckForUnloadedInstances(GetIndex()); -#endif // CHECK_APP_DOMAIN_LEAKS { GCX_PREEMP(); RemoveMemoryPressure(); diff --git a/src/vm/appdomain.hpp b/src/vm/appdomain.hpp index ea1c471759..d92aabb535 100644 --- a/src/vm/appdomain.hpp +++ b/src/vm/appdomain.hpp @@ -1290,10 +1290,6 @@ public: OBJECTHANDLE CreatePinningHandle(OBJECTREF object) { WRAPPER_NO_CONTRACT; -#if CHECK_APP_DOMAIN_LEAKS - if(IsAppDomain()) - object->TryAssignAppDomain((AppDomain*)this,TRUE); -#endif return ::CreatePinningHandle(m_handleStore, object); } diff --git a/src/vm/arm/stubs.cpp b/src/vm/arm/stubs.cpp index 7e5b58c54b..38009167e3 100644 --- a/src/vm/arm/stubs.cpp +++ b/src/vm/arm/stubs.cpp @@ -2512,11 +2512,6 @@ void InitJITHelpers1() { STANDARD_VM_CONTRACT; -#if CHECK_APP_DOMAIN_LEAKS - if(g_pConfig->AppDomainLeaks()) - SetJitHelperFunction(CORINFO_HELP_ARRADDR_ST, JIT_Stelem_Ref_Portable); -#endif - // Allocation helpers, faster but non-logging. if (!(TrackAllocationsEnabled() || LoggingOn(LF_GCALLOC, LL_INFO10) diff --git a/src/vm/array.cpp b/src/vm/array.cpp index 3a33aff43a..08a86a39d7 100644 --- a/src/vm/array.cpp +++ b/src/vm/array.cpp @@ -432,7 +432,7 @@ MethodTable* Module::CreateArrayMethodTable(TypeHandle elemTypeHnd, CorElementTy pClass->SetArrayElementType (elemType); pClass->SetMethodTable (pMT); -#if defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#if defined(_DEBUG) // Non-covariant arrays of agile types are agile if (elemType != ELEMENT_TYPE_CLASS && elemTypeHnd.IsAppDomainAgile()) pClass->SetAppDomainAgile(); diff --git a/src/vm/callhelpers.cpp b/src/vm/callhelpers.cpp index c575ee615d..c555751c23 100644 --- a/src/vm/callhelpers.cpp +++ b/src/vm/callhelpers.cpp @@ -418,20 +418,6 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT * } #endif // DEBUGGING_SUPPORTED -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - { - // See if we are in the correct domain to call on the object - if (m_methodSig.HasThis() && !m_pMD->GetMethodTable()->IsValueType()) - { - CONTRACT_VIOLATION(ThrowsViolation|GCViolation|FaultViolation); - OBJECTREF pThis = ArgSlotToObj(pArguments[0]); - if (!pThis->AssignAppDomain(GetAppDomain())) - _ASSERTE(!"Attempt to call method on object in wrong domain"); - } - } -#endif // CHECK_APP_DOMAIN_LEAKS - #ifdef _DEBUG { #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING @@ -547,17 +533,6 @@ void MethodDescCallSite::CallTargetWorker(const ARG_SLOT *pArguments, ARG_SLOT * } #endif -#if CHECK_APP_DOMAIN_LEAKS - // Make sure the arg is in the right app domain - if (g_pConfig->AppDomainLeaks() && m_argIt.GetArgType() == ELEMENT_TYPE_CLASS) - { - CONTRACT_VIOLATION(ThrowsViolation|GCViolation|FaultViolation); - OBJECTREF objRef = ArgSlotToObj(pArguments[arg]); - if (!objRef->AssignAppDomain(GetAppDomain())) - _ASSERTE(!"Attempt to pass object in wrong app domain to method"); - } -#endif // CHECK_APP_DOMAIN_LEAKS - ArgDestination argDest(pTransitionBlock, ofs, m_argIt.GetArgLocDescForStructInRegs()); UINT32 stackSize = m_argIt.GetArgSize(); diff --git a/src/vm/class.cpp b/src/vm/class.cpp index 99156ffb59..ea02ca7bd9 100644 --- a/src/vm/class.cpp +++ b/src/vm/class.cpp @@ -1034,7 +1034,7 @@ CorElementType EEClass::ComputeInternalCorElementTypeForValueType(MethodTable * return ELEMENT_TYPE_VALUETYPE; } -#if defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#if defined(_DEBUG) //******************************************************************************* void EEClass::GetPredefinedAgility(Module *pModule, mdTypeDef td, BOOL *pfIsAgile, BOOL *pfCheckAgile) @@ -1506,7 +1506,7 @@ exit: LOG((LF_CLASSLOADER, LL_INFO1000, "CLASSLOADER: AppDomainAgileAttribute for %s is %d\n", pClass->GetDebugClassName(), pClass->IsAppDomainAgile())); pClass->SetAppDomainAgilityDone(); } -#endif // defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#endif // defined(_DEBUG) //******************************************************************************* // diff --git a/src/vm/class.h b/src/vm/class.h index 8bbbf55b9b..5e349f75b1 100644 --- a/src/vm/class.h +++ b/src/vm/class.h @@ -1793,7 +1793,7 @@ public: SigPointer sp, CorGenericParamAttr position); -#if defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#if defined(_DEBUG) public: enum{ AUXFLAG_APP_DOMAIN_AGILE = 0x00000001, @@ -1890,7 +1890,7 @@ public: static void SetAppDomainAgileAttribute(MethodTable * pMT); static void GetPredefinedAgility(Module *pModule, mdTypeDef td, BOOL *pfIsAgile, BOOL *pfIsCheckAgile); -#endif // defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#endif // defined(_DEBUG) //------------------------------------------------------------- // CONCRETE DATA LAYOUT @@ -2033,10 +2033,10 @@ private: DWORD m_VMFlags; /* - * We maintain some auxillary flags in DEBUG or CHECK_APP_DOMAIN_LEAKS builds, + * We maintain some auxillary flags in DEBUG builds, * this frees up some bits in m_wVMFlags */ -#if defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#if defined(_DEBUG) WORD m_wAuxFlags; #endif diff --git a/src/vm/clrex.cpp b/src/vm/clrex.cpp index 3b21d649d6..930ac5d6d1 100644 --- a/src/vm/clrex.cpp +++ b/src/vm/clrex.cpp @@ -2527,35 +2527,6 @@ CLRLastThrownObjectException* CLRLastThrownObjectException::Validate() "To suppress this assert 'set COMPlus_SuppressLostExceptionTypeAssert=1'"); } } - else - { // If there IS a LastThrownObject, then, for - // exceptions other than the pre-allocated ones... - if (!CLRException::IsPreallocatedExceptionObject(throwable)) - { // ...check that the exception is from the current appdomain. -#if CHECK_APP_DOMAIN_LEAKS - if (!throwable->CheckAppDomain(GetAppDomain())) - { // We've lost track of the exception's type. Raise an assert. (This is configurable to allow - // stress labs to turn off the assert.) - - static int iSuppress = -1; - if (iSuppress == -1) - iSuppress = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_SuppressLostExceptionTypeAssert); - if (!iSuppress) - { - // Raising an assert message can cause a mode violation. - CONTRACT_VIOLATION(ModeViolation); - - // Use DbgAssertDialog to get the formatting right. - DbgAssertDialog(__FILE__, __LINE__, - "The 'LastThrownObject' does not belong to the current appdomain.\n" - "The runtime may have lost track of the type of an exception in flight.\n" - "Please get a good stack trace, find the caller of Validate, and file a bug against the owner.\n\n" - "To suppress this assert 'set COMPlus_SuppressLostExceptionTypeAssert=1'"); - } - } -#endif - } - } GCPROTECT_END(); diff --git a/src/vm/common.h b/src/vm/common.h index 54ebf362c9..1008533ddd 100644 --- a/src/vm/common.h +++ b/src/vm/common.h @@ -265,10 +265,6 @@ FORCEINLINE void* memcpyUnsafe(void *dest, const void *src, size_t len) extern "C" void * __cdecl GCSafeMemCpy(void *, const void *, size_t); #define memcpy(dest, src, len) GCSafeMemCpy(dest, src, len) #endif // !defined(memcpy) - - #if !defined(CHECK_APP_DOMAIN_LEAKS) - #define CHECK_APP_DOMAIN_LEAKS 1 - #endif #else // !_DEBUG && !DACCESS_COMPILE && !CROSSGEN_COMPILE FORCEINLINE void* memcpyNoGCRefs(void * dest, const void * src, size_t len) { WRAPPER_NO_CONTRACT; diff --git a/src/vm/excep.cpp b/src/vm/excep.cpp index 7e182dc787..35a207457c 100644 --- a/src/vm/excep.cpp +++ b/src/vm/excep.cpp @@ -2931,21 +2931,6 @@ VOID DECLSPEC_NORETURN RaiseTheExceptionInternalOnly(OBJECTREF throwable, BOOL r _ASSERTE(param.pThread); param.pExState = param.pThread->GetExceptionState(); - // Make sure that the object being thrown belongs in the current appdomain. - #if defined(_DEBUG) && CHECK_APP_DOMAIN_LEAKS - if (param.throwable != NULL) - { - GCPROTECT_BEGIN(param.throwable); - if (!CLRException::IsPreallocatedExceptionObject(param.throwable)) - _ASSERTE(param.throwable->CheckAppDomain(GetAppDomain())); - GCPROTECT_END(); - } - else - { // throwable is NULL -- that shouldn't happen - _ASSERTE(NingenEnabled() || param.throwable != NULL); - } - #endif - if (param.pThread->IsRudeAbortInitiated()) { // Nobody should be able to swallow rude thread abort. diff --git a/src/vm/field.cpp b/src/vm/field.cpp index defccd7269..78cb7f5bd0 100644 --- a/src/vm/field.cpp +++ b/src/vm/field.cpp @@ -62,10 +62,6 @@ VOID FieldDesc::Init(mdFieldDef mb, CorElementType FieldType, DWORD dwMemberAttr m_debugName = (LPUTF8)pszFieldName; #endif -#if CHECK_APP_DOMAIN_LEAKS - m_isDangerousAppDomainAgileField = 0; -#endif - _ASSERTE(GetMemberDef() == mb); // no truncation _ASSERTE(GetFieldType() == FieldType); _ASSERTE(GetFieldProtection() == (fdFieldAccessMask & dwMemberAttrs)); diff --git a/src/vm/field.h b/src/vm/field.h index 52b9d682cd..8d5b17fb71 100644 --- a/src/vm/field.h +++ b/src/vm/field.h @@ -313,7 +313,7 @@ public: ); } -#if defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#if defined(_DEBUG) BOOL IsDangerousAppDomainAgileField() { LIMITED_METHOD_CONTRACT; diff --git a/src/vm/finalizerthread.cpp b/src/vm/finalizerthread.cpp index 2955decbd7..7d9e8abba8 100644 --- a/src/vm/finalizerthread.cpp +++ b/src/vm/finalizerthread.cpp @@ -147,13 +147,6 @@ Object * FinalizerThread::DoOneFinalization(Object* fobj, Thread* pThread,int bi { // if can't get into domain to finalize it, then it must be agile so finalize in current domain targetAppDomain = currentDomain; -#if CHECK_APP_DOMAIN_LEAKS - { - // object must be agile if can't get into it's domain - if (g_pConfig->AppDomainLeaks() && !fobj->TrySetAppDomainAgile(FALSE)) - _ASSERTE(!"Found non-agile GC object which should have been finalized during app domain unload."); - } -#endif } if (targetAppDomain == currentDomain) diff --git a/src/vm/frames.cpp b/src/vm/frames.cpp index d7210fc3ff..38815bf757 100644 --- a/src/vm/frames.cpp +++ b/src/vm/frames.cpp @@ -41,11 +41,7 @@ #include "argdestination.h" -#if CHECK_APP_DOMAIN_LEAKS -#define CHECK_APP_DOMAIN GC_CALL_CHECK_APP_DOMAIN -#else #define CHECK_APP_DOMAIN 0 -#endif //----------------------------------------------------------------------- #if _DEBUG diff --git a/src/vm/gcenv.ee.common.cpp b/src/vm/gcenv.ee.common.cpp index ca7349091f..6ec5735e2c 100644 --- a/src/vm/gcenv.ee.common.cpp +++ b/src/vm/gcenv.ee.common.cpp @@ -191,10 +191,6 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData) Frame *pFrame; GCCONTEXT *gcctx = (GCCONTEXT*) pData; -#if CHECK_APP_DOMAIN_LEAKS - gcctx->sc->pCurrentDomain = pCF->GetAppDomain(); -#endif //CHECK_APP_DOMAIN_LEAKS - #ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING if (g_fEnableARM) { diff --git a/src/vm/gchandleutilities.cpp b/src/vm/gchandleutilities.cpp index 7433945951..9345a18429 100644 --- a/src/vm/gchandleutilities.cpp +++ b/src/vm/gchandleutilities.cpp @@ -20,19 +20,6 @@ void ValidateObjectAndAppDomain(OBJECTREF objRef, ADIndex appDomainIndex) assert(domain != nullptr); assert(!domain->NoAccessToHandleTable()); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks() && objRef != NULL) - { - if (appDomainIndex.m_dwIndex) - { - objRef->TryAssignAppDomain(domain); - } - else - { - objRef->TrySetAppDomainAgile(); - } - } -#endif // CHECK_APP_DOMAIN_LEAKS #endif // _DEBUG_IMPL } diff --git a/src/vm/gchelpers.cpp b/src/vm/gchelpers.cpp index 046f06e2d5..4684edeaf5 100644 --- a/src/vm/gchelpers.cpp +++ b/src/vm/gchelpers.cpp @@ -628,11 +628,6 @@ OBJECTREF AllocateArrayEx(MethodTable *pArrayMT, INT32 *pArgs, DWORD dwNumArgs, orArray = (ArrayBase *) OBJECTREFToObject(objref); #endif -#if CHECK_APP_DOMAIN_LEAKS - if (!bDontSetAppDomain && g_pConfig->AppDomainLeaks()) - orArray->SetAppDomain(); -#endif - if (kind == ELEMENT_TYPE_ARRAY) { INT32 *pCountsPtr = (INT32 *) orArray->GetBoundsPtr(); @@ -859,11 +854,6 @@ OBJECTREF FastAllocatePrimitiveArray(MethodTable* pMT, DWORD cElements, BOOL b g_IBCLogger.LogMethodTableAccess(pMT); LogAlloc(totalSize, pMT, orObject); - -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - orObject->SetAppDomain(); -#endif return( ObjectToOBJECTREF((Object*)orObject) ); } @@ -1066,11 +1056,6 @@ STRINGREF SlowAllocateString( DWORD cchStringLength ) LogAlloc(ObjectSize, g_pStringClass, orObject); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - orObject->SetAppDomain(); -#endif - return( ObjectToSTRINGREF(orObject) ); } @@ -1187,11 +1172,6 @@ OBJECTREF AllocateObject(MethodTable *pMT orObject->SetMethodTable(pMT); } -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - orObject->SetAppDomain(); - else -#endif if (pMT->HasFinalizer()) orObject->SetAppDomain(); diff --git a/src/vm/gcinfodecoder.cpp b/src/vm/gcinfodecoder.cpp index 7c0881c880..558247c9bf 100644 --- a/src/vm/gcinfodecoder.cpp +++ b/src/vm/gcinfodecoder.cpp @@ -10,12 +10,8 @@ #ifdef USE_GC_INFO_DECODER #ifndef CHECK_APP_DOMAIN -#if CHECK_APP_DOMAIN_LEAKS -#define CHECK_APP_DOMAIN GC_CALL_CHECK_APP_DOMAIN -#else #define CHECK_APP_DOMAIN 0 #endif -#endif #ifndef GCINFODECODER_CONTRACT #define GCINFODECODER_CONTRACT LIMITED_METHOD_CONTRACT diff --git a/src/vm/i386/jitinterfacex86.cpp b/src/vm/i386/jitinterfacex86.cpp index 3994c2e216..642c417598 100644 --- a/src/vm/i386/jitinterfacex86.cpp +++ b/src/vm/i386/jitinterfacex86.cpp @@ -58,11 +58,6 @@ private: static void EmitDummyObject(CPUSTUBLINKER *psl, X86Reg regTestAlign, Flags flags); static void EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel *noAlloc, Flags flags); static void EmitNoAllocCode(CPUSTUBLINKER *psl, Flags flags); - -#if CHECK_APP_DOMAIN_LEAKS - static void EmitSetAppDomain(CPUSTUBLINKER *psl); - static void EmitCheckRestore(CPUSTUBLINKER *psl); -#endif }; extern "C" LONG g_global_alloc_lock; @@ -113,10 +108,6 @@ __declspec(naked) void F_CALL_CONV JIT_Stelem_Ref(PtrArray* array, unsigned idx, STATIC_CONTRACT_GC_TRIGGERS; enum { CanCast = TypeHandle::CanCast, -#if CHECK_APP_DOMAIN_LEAKS - EEClassFlags = EEClass::AUXFLAG_APP_DOMAIN_AGILE | - EEClass::AUXFLAG_CHECK_APP_DOMAIN_AGILE, -#endif // CHECK_APP_DOMAIN_LEAKS }; __asm { @@ -131,25 +122,6 @@ __declspec(naked) void F_CALL_CONV JIT_Stelem_Ref(PtrArray* array, unsigned idx, test EAX, EAX jz Assigning0 -#if CHECK_APP_DOMAIN_LEAKS - mov EAX,[g_pConfig] - movzx EAX, [EAX]EEConfig.fAppDomainLeaks; - test EAX, EAX - jz NoCheck - // Check if the instance is agile or check agile - mov EAX, [ECX] - mov EAX, [EAX]MethodTable.m_ElementTypeHnd - test EAX, 2 // Check for non-MT - jnz NoCheck - // Check VMflags of element type - mov EAX, [EAX]MethodTable.m_pEEClass - mov EAX, dword ptr [EAX]EEClass.m_wAuxFlags - test EAX, EEClassFlags - jnz NeedFrame // Jump to the generic case so we can do an app domain check - NoCheck: - mov EAX, [ESP+4] // EAX = val -#endif // CHECK_APP_DOMAIN_LEAKS - push EDX mov EDX, [ECX] mov EDX, [EDX]MethodTable.m_ElementTypeHnd @@ -192,9 +164,6 @@ NotExactMatch: cmp EAX, CanCast je DoWrite -#if CHECK_APP_DOMAIN_LEAKS -NeedFrame: -#endif // Call the helper that knows how to erect a frame push EDX push ECX @@ -424,21 +393,6 @@ void STDCALL JIT_TailCallHelper(Thread * pThread) } #endif // FEATURE_HIJACK -#if CHECK_APP_DOMAIN_LEAKS -HCIMPL1(void *, SetObjectAppDomain, Object *pObject) -{ - FCALL_CONTRACT; - DEBUG_ONLY_FUNCTION; - - HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_NOPOLL(Frame::FRAME_ATTR_CAPTURE_DEPTH_2|Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_NO_THREAD_ABORT); - pObject->SetAppDomain(); - HELPER_METHOD_FRAME_END(); - - return pObject; -} -HCIMPLEND -#endif // CHECK_APP_DOMAIN_LEAKS - // emit code that adds MIN_OBJECT_SIZE to reg if reg is unaligned thus making it aligned void JIT_TrialAlloc::EmitAlignmentRoundup(CPUSTUBLINKER *psl, X86Reg testAlignReg, X86Reg adjReg, Flags flags) { @@ -497,10 +451,6 @@ void JIT_TrialAlloc::EmitDummyObject(CPUSTUBLINKER *psl, X86Reg alignTestReg, Fl // mov [EAX], EDX psl->X86EmitOffsetModRM(0x89, kEDX, kEAX, 0); -#if CHECK_APP_DOMAIN_LEAKS - EmitSetAppDomain(psl); -#endif - // add EAX, MIN_OBJECT_SIZE psl->X86EmitAddReg(kEAX, MIN_OBJECT_SIZE); @@ -652,52 +602,6 @@ void JIT_TrialAlloc::EmitCore(CPUSTUBLINKER *psl, CodeLabel *noLock, CodeLabel * #endif // INCREMENTAL_MEMCLR } -#if CHECK_APP_DOMAIN_LEAKS -void JIT_TrialAlloc::EmitSetAppDomain(CPUSTUBLINKER *psl) -{ - STANDARD_VM_CONTRACT; - - if (!g_pConfig->AppDomainLeaks()) - return; - - // At both entry & exit, eax contains the allocated object. - // ecx is preserved, edx is not. - - // - // Add in a call to SetAppDomain. (Note that this - // probably would have been easier to implement by just not using - // the generated helpers in a checked build, but we'd lose code - // coverage that way.) - // - - // Save ECX over function call - psl->X86EmitPushReg(kECX); - -#ifdef UNIX_X86_ABI -#define STACK_ALIGN_PADDING 8 - // sub esp, STACK_ALIGN_PADDING; to align the stack - psl->X86EmitSubEsp(STACK_ALIGN_PADDING); -#endif // UNIX_X86_ABI - - // mov object to ECX - // mov ecx, eax - psl->Emit16(0xc88b); - - // SetObjectAppDomain pops its arg & returns object in EAX - psl->X86EmitCall(psl->NewExternalCodeLabel((LPVOID)SetObjectAppDomain), 4); - -#ifdef UNIX_X86_ABI - // add esp, STACK_ALIGN_PADDING - psl->X86EmitAddEsp(STACK_ALIGN_PADDING); -#undef STACK_ALIGN_PADDING -#endif // UNIX_X86_ABI - - psl->X86EmitPopReg(kECX); -} - -#endif // CHECK_APP_DOMAIN_LEAKS - - void JIT_TrialAlloc::EmitNoAllocCode(CPUSTUBLINKER *psl, Flags flags) { STANDARD_VM_CONTRACT; @@ -728,10 +632,6 @@ void *JIT_TrialAlloc::GenAllocSFast(Flags flags) // Emit the main body of the trial allocator, be it SP or MP EmitCore(&sl, noLock, noAlloc, flags); -#if CHECK_APP_DOMAIN_LEAKS - EmitSetAppDomain(&sl); -#endif - // Here we are at the end of the success case - just emit a ret sl.X86EmitReturn(0); @@ -786,10 +686,6 @@ void *JIT_TrialAlloc::GenBox(Flags flags) // Emit the main body of the trial allocator EmitCore(&sl, noLock, noAlloc, flags); -#if CHECK_APP_DOMAIN_LEAKS - EmitSetAppDomain(&sl); -#endif - // Here we are at the end of the success case // Check whether the object contains pointers @@ -1082,10 +978,6 @@ void *JIT_TrialAlloc::GenAllocArray(Flags flags) // mov dword ptr [eax]ArrayBase.m_NumComponents, edx sl.X86EmitIndexRegStore(kEAX, offsetof(ArrayBase,m_NumComponents), kEDX); -#if CHECK_APP_DOMAIN_LEAKS - EmitSetAppDomain(&sl); -#endif - // no stack parameters sl.X86EmitReturn(0); @@ -1198,10 +1090,6 @@ void *JIT_TrialAlloc::GenAllocString(Flags flags) // mov dword ptr [eax]ArrayBase.m_StringLength, ecx sl.X86EmitIndexRegStore(kEAX, offsetof(StringObject,m_StringLength), kECX); -#if CHECK_APP_DOMAIN_LEAKS - EmitSetAppDomain(&sl); -#endif - // no stack parameters sl.X86EmitReturn(0); diff --git a/src/vm/jithelpers.cpp b/src/vm/jithelpers.cpp index 9f887e6616..48b8b94808 100644 --- a/src/vm/jithelpers.cpp +++ b/src/vm/jithelpers.cpp @@ -2777,13 +2777,6 @@ HCIMPL1(Object*, JIT_NewS_MP_FastPortable, CORINFO_CLASS_HANDLE typeHnd_) _ASSERTE(object->HasEmptySyncBlockInfo()); object->SetMethodTable(methodTable); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - { - object->SetAppDomain(); - } -#endif // CHECK_APP_DOMAIN_LEAKS - return object; } while (false); @@ -2880,13 +2873,6 @@ HCIMPL1(StringObject*, AllocateString_MP_FastPortable, DWORD stringLength) stringObject->SetStringLength(stringLength); _ASSERTE(stringObject->GetBuffer()[stringLength] == W('\0')); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - { - stringObject->SetAppDomain(); - } -#endif // CHECK_APP_DOMAIN_LEAKS - return stringObject; } while (false); @@ -3055,13 +3041,6 @@ HCIMPL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, IN _ASSERTE(static_cast<DWORD>(componentCount) == componentCount); array->m_NumComponents = static_cast<DWORD>(componentCount); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - { - array->SetAppDomain(); - } -#endif // CHECK_APP_DOMAIN_LEAKS - return array; } while (false); @@ -3121,13 +3100,6 @@ HCIMPL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, I _ASSERTE(static_cast<DWORD>(componentCount) == componentCount); array->m_NumComponents = static_cast<DWORD>(componentCount); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - { - array->SetAppDomain(); - } -#endif // CHECK_APP_DOMAIN_LEAKS - return array; } while (false); @@ -3369,11 +3341,6 @@ HCIMPL2(LPVOID, ArrayStoreCheck, Object** pElement, PtrArray** pArray) GCStress<cfg_any, EeconfigFastGcSPolicy>::MaybeTrigger(); -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->AppDomainLeaks()) - (*pElement)->AssignAppDomain((*pArray)->GetAppDomain()); -#endif // CHECK_APP_DOMAIN_LEAKS - if (!ObjIsInstanceOf(*pElement, (*pArray)->GetArrayElementTypeHandle())) COMPlusThrow(kArrayTypeMismatchException); @@ -3404,22 +3371,6 @@ HCIMPL3(void, JIT_Stelem_Ref_Portable, PtrArray* array, unsigned idx, Object *va MethodTable *valMT = val->GetMethodTable(); TypeHandle arrayElemTH = array->GetArrayElementTypeHandle(); -#if CHECK_APP_DOMAIN_LEAKS - // If the instance is agile or check agile - if (g_pConfig->AppDomainLeaks() && !arrayElemTH.IsAppDomainAgile() && !arrayElemTH.IsCheckAppDomainAgile()) - { - // FCALL_CONTRACT increase ForbidGC count. Normally, HELPER_METHOD_FRAME macros decrease the count. - // But to avoid perf hit, we manually decrease the count here before calling another HCCALL. - ENDFORBIDGC(); - - if (HCCALL2(ArrayStoreCheck,(Object**)&val, (PtrArray**)&array) != NULL) - { - // This return is never executed. It helps epilog walker to find its way out. - return; - } - } - else -#endif if (arrayElemTH != TypeHandle(valMT) && arrayElemTH != TypeHandle(g_pObjectClass)) { TypeHandle::CastResult result = ObjIsInstanceOfNoGC(val, arrayElemTH); diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp index 5340e2ddb0..874beae85b 100644 --- a/src/vm/jitinterface.cpp +++ b/src/vm/jitinterface.cpp @@ -1645,24 +1645,6 @@ void CEEInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, { BOOL fInstanceHelper = FALSE; -#if CHECK_APP_DOMAIN_LEAKS - if (g_pConfig->EnableFullDebug() - && pField->IsDangerousAppDomainAgileField() - && CorTypeInfo::IsObjRef(pField->GetFieldType())) - { - // - // In a checked field with all checks turned on, we use a helper to enforce the app domain - // agile invariant. - // - // <REVISIT_TODO>@todo: we'd like to check this for value type fields as well - we - // just need to add some code to iterate through the fields for - // references during the assignment. - // </REVISIT_TODO> - fInstanceHelper = TRUE; - } - else -#endif // CHECK_APP_DOMAIN_LEAKS - if (fInstanceHelper) { if (flags & CORINFO_ACCESS_ADDRESS) diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 725fb2d863..1a6b39af5c 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -1904,7 +1904,7 @@ MethodTableBuilder::BuildMethodTableThrowing( SetFinalizationSemantics(); -#if defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#if defined(_DEBUG) // Figure out if we're domain agile.. // Note that this checks a bunch of field directly on the class & method table, // so it needs to come late in the game. diff --git a/src/vm/object.cpp b/src/vm/object.cpp index 32d066c708..aff6a835ae 100644 --- a/src/vm/object.cpp +++ b/src/vm/object.cpp @@ -422,38 +422,6 @@ AppDomain *Object::GetAppDomain() return NULL; AppDomain *pDomain = SystemDomain::TestGetAppDomainAtIndex(index); - -#if CHECK_APP_DOMAIN_LEAKS - if (! g_pConfig->AppDomainLeaks()) - return pDomain; - - if (IsAppDomainAgile()) - return NULL; - - // - // If an object has an index of an unloaded domain (its ok to be of a - // domain where an unload is in progress through), go ahead - // and make it agile. If this fails, we have an invalid reference - // to an unloaded domain. If it succeeds, the object is no longer - // contained in that app domain so we can continue. - // - - if (pDomain == NULL) - { - if (SystemDomain::IndexOfAppDomainBeingUnloaded() == index) { - // if appdomain is unloading but still alive and is valid to have instances - // in that domain, then use it. - AppDomain *tmpDomain = SystemDomain::AppDomainBeingUnloaded(); - if (tmpDomain && tmpDomain->ShouldHaveInstances()) - pDomain = tmpDomain; - } - if (!pDomain && ! TrySetAppDomainAgile(FALSE)) - { - _ASSERTE(!"Attempt to reference an object belonging to an unloaded domain"); - } - } -#endif - return pDomain; } @@ -483,826 +451,6 @@ CHARARRAYREF AllocateCharArray(DWORD dwArrayLength) return (CHARARRAYREF)AllocatePrimitiveArray(ELEMENT_TYPE_CHAR, dwArrayLength); } -#if CHECK_APP_DOMAIN_LEAKS - -BOOL Object::IsAppDomainAgile() -{ - WRAPPER_NO_CONTRACT; - DEBUG_ONLY_FUNCTION; - - SyncBlock *psb = PassiveGetSyncBlock(); - - if (psb) - { - if (psb->IsAppDomainAgile()) - return TRUE; - if (psb->IsCheckedForAppDomainAgile()) - return FALSE; - } - return CheckAppDomain(NULL); -} - -BOOL Object::TrySetAppDomainAgile(BOOL raiseAssert) -{ - LIMITED_METHOD_CONTRACT; - FAULT_NOT_FATAL(); - DEBUG_ONLY_FUNCTION; - - BOOL ret = TRUE; - - EX_TRY - { - ret = SetAppDomainAgile(raiseAssert); - } - EX_CATCH{} - EX_END_CATCH(SwallowAllExceptions); - - return ret; -} - - -BOOL Object::ShouldCheckAppDomainAgile (BOOL raiseAssert, BOOL *pfResult) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - DEBUG_ONLY_FUNCTION; - - if (!g_pConfig->AppDomainLeaks()) - { - *pfResult = TRUE; - return FALSE; - } - - if (this == NULL) - { - *pfResult = TRUE; - return FALSE; - } - - if (IsAppDomainAgile()) - { - *pfResult = TRUE; - return FALSE; - } - - // if it's not agile and we've already checked it, just bail early - if (IsCheckedForAppDomainAgile()) - { - *pfResult = FALSE; - return FALSE; - } - - if (IsTypeNeverAppDomainAgile()) - { - if (raiseAssert) - _ASSERTE(!"Attempt to reference a domain bound object from an agile location"); - *pfResult = FALSE; - return FALSE; - } - - // - // Do not allow any object to be set to be agile unless we - // are compiling field access checking into the class. This - // will help guard against unintentional "agile" propagation - // as well. - // - - if (!IsTypeAppDomainAgile() && !IsTypeCheckAppDomainAgile()) - { - if (raiseAssert) - _ASSERTE(!"Attempt to reference a domain bound object from an agile location"); - *pfResult = FALSE; - return FALSE; - } - - return TRUE; -} - - -BOOL Object::SetAppDomainAgile(BOOL raiseAssert, SetAppDomainAgilePendingTable *pTable) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - INJECT_FAULT(COMPlusThrowOM();); - DEBUG_ONLY; - } - CONTRACTL_END; - BEGIN_DEBUG_ONLY_CODE; - BOOL fResult; - if (!this->ShouldCheckAppDomainAgile(raiseAssert, &fResult)) - return fResult; - - // - // If a SetAppDomainAgilePendingTable is provided, then SetAppDomainAgile - // was called via SetAppDomainAgile. Simply store this object in the - // table, and let the calling SetAppDomainAgile process it later in a - // non-recursive manner. - // - - if (pTable == NULL) - { - pTable = (SetAppDomainAgilePendingTable *)ClrFlsGetValue(TlsIdx_AppDomainAgilePendingTable); - } - if (pTable) - { - // - // If the object is already being checked (on this thread or another), - // don't duplicate the effort. Return TRUE to tell the caller to - // continue processing other references. Since we're just testing - // the bit we don't need to take the spin lock. - // - - ObjHeader* pOh = this->GetHeader(); - _ASSERTE(pOh); - - if (pOh->GetBits() & BIT_SBLK_AGILE_IN_PROGRESS) - { - return TRUE; - } - - pTable->PushReference(this); - } - else - { - // - // Initialize the table of pending objects - // - - SetAppDomainAgilePendingTable table; - class ResetPendingTable - { - public: - ResetPendingTable(SetAppDomainAgilePendingTable *pTable) - { - ClrFlsSetValue(TlsIdx_AppDomainAgilePendingTable, pTable); - } - ~ResetPendingTable() - { - ClrFlsSetValue(TlsIdx_AppDomainAgilePendingTable, NULL); - } - }; - - ResetPendingTable resetPendingTable(&table); - - // - // Iterate over the table, processing all referenced objects until the - // entire graph has its sync block marked, or a non-agile object is - // found. The loop will start with the current object, as though we - // just removed it from the table as a pending reference. - // - - Object *pObject = this; - - do - { - // - // Mark the object to identify recursion. - // ~SetAppDomainAgilePendingTable will clean up - // BIT_SBLK_AGILE_IN_PROGRESS, so attempt to push the object first - // in case it needs to throw an exception. - // - - table.PushParent(pObject); - - ObjHeader* pOh = pObject->GetHeader(); - _ASSERTE(pOh); - - bool fInProgress = false; - - { - ENTER_SPIN_LOCK(pOh); - { - if (pOh->GetBits() & BIT_SBLK_AGILE_IN_PROGRESS) - { - fInProgress = true; - } - else - { - pOh->SetBit(BIT_SBLK_AGILE_IN_PROGRESS); - } - } - LEAVE_SPIN_LOCK(pOh); - } - - if (fInProgress) - { - // - // Object is already being processed, so just remove it from - // the table and look for another object. - // - - bool fReturnedToParent = false; - Object *pLastObject = table.GetPendingObject(&fReturnedToParent); - CONSISTENCY_CHECK(pLastObject == pObject && fReturnedToParent); - } - else - { - - // - // Finish processing this object. Any references will be added to - // the table. - // - - if (!pObject->SetAppDomainAgileWorker(raiseAssert, &table)) - return FALSE; - } - - // - // Find the next object to explore. - // - - for (;;) - { - bool fReturnedToParent; - pObject = table.GetPendingObject(&fReturnedToParent); - - // - // No more objects in the table? - // - - if (!pObject) - break; - - // - // If we've processed all objects reachable through an object, - // then clear BIT_SBLK_AGILE_IN_PROGRESS, and look for another - // object in the table. - // - - if (fReturnedToParent) - { - pOh = pObject->GetHeader(); - _ASSERTE(pOh); - - ENTER_SPIN_LOCK(pOh); - pOh->ClrBit(BIT_SBLK_AGILE_IN_PROGRESS); - LEAVE_SPIN_LOCK(pOh); - } - else - { - // - // Re-check whether we should explore through this reference. - // - - if (pObject->ShouldCheckAppDomainAgile(raiseAssert, &fResult)) - break; - - if (!fResult) - return FALSE; - } - } - } - while (pObject); - } - END_DEBUG_ONLY_CODE; - return TRUE; -} - - -BOOL Object::SetAppDomainAgileWorker(BOOL raiseAssert, SetAppDomainAgilePendingTable *pTable) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - DEBUG_ONLY_FUNCTION; - - BOOL ret = TRUE; - - if (! IsTypeAppDomainAgile() && ! SetFieldsAgile(raiseAssert, pTable)) - { - SetIsCheckedForAppDomainAgile(); - - ret = FALSE; - } - - if (ret) - { - SetSyncBlockAppDomainAgile(); - } - - return ret; -} - - -SetAppDomainAgilePendingTable::SetAppDomainAgilePendingTable () - : m_Stack(sizeof(PendingEntry)) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - DEBUG_ONLY_FUNCTION; -} - - -SetAppDomainAgilePendingTable::~SetAppDomainAgilePendingTable () -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - DEBUG_ONLY_FUNCTION; - - while (TRUE) - { - Object *pObj; - bool fObjMarked; - pObj = GetPendingObject(&fObjMarked); - if (pObj == NULL) - { - break; - } - - if (fObjMarked) - { - ObjHeader* pOh = pObj->GetHeader(); - _ASSERTE(pOh); - - ENTER_SPIN_LOCK(pOh); - pOh->ClrBit(BIT_SBLK_AGILE_IN_PROGRESS); - LEAVE_SPIN_LOCK(pOh); - } -} -} - - -void Object::SetSyncBlockAppDomainAgile() -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - DEBUG_ONLY_FUNCTION; - - SyncBlock *psb = PassiveGetSyncBlock(); - if (! psb) - { - psb = GetSyncBlock(); - } - psb->SetIsAppDomainAgile(); -} - -#if CHECK_APP_DOMAIN_LEAKS -BOOL Object::CheckAppDomain(AppDomain *pAppDomain) -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - DEBUG_ONLY_FUNCTION; - - if (!g_pConfig->AppDomainLeaks()) - return TRUE; - - if (this == NULL) - return TRUE; - - if (IsAppDomainAgileRaw()) - return TRUE; - -#ifndef _DEBUG - MethodTable *pMT = GetGCSafeMethodTable(); - - if (!pMT->IsDomainNeutral()) - return pAppDomain == pMT->GetDomain(); -#endif - - ADIndex index = GetHeader()->GetAppDomainIndex(); - - _ASSERTE(index.m_dwIndex != 0); - - return (pAppDomain != NULL && index == pAppDomain->GetIndex()); -} -#endif - -BOOL Object::IsTypeAppDomainAgile() -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - DEBUG_ONLY_FUNCTION; - - MethodTable *pMT = GetGCSafeMethodTable(); - - if (pMT->IsArray()) - { - TypeHandle th = pMT->GetApproxArrayElementTypeHandle(); - return th.IsArrayOfElementsAppDomainAgile(); - } - else - return pMT->GetClass()->IsAppDomainAgile(); -} - -BOOL Object::IsTypeCheckAppDomainAgile() -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - DEBUG_ONLY_FUNCTION; - - MethodTable *pMT = GetGCSafeMethodTable(); - - if (pMT->IsArray()) - { - TypeHandle th = pMT->GetApproxArrayElementTypeHandle(); - return th.IsArrayOfElementsCheckAppDomainAgile(); - } - else - return pMT->GetClass()->IsCheckAppDomainAgile(); -} - -BOOL Object::IsTypeNeverAppDomainAgile() -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - DEBUG_ONLY_FUNCTION; - - return !IsTypeAppDomainAgile() && !IsTypeCheckAppDomainAgile(); -} - -BOOL Object::IsTypeTypesafeAppDomainAgile() -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - DEBUG_ONLY_FUNCTION; - - return IsTypeAppDomainAgile() && !IsTypeCheckAppDomainAgile(); -} - -BOOL Object::TryAssignAppDomain(AppDomain *pAppDomain, BOOL raiseAssert) -{ - LIMITED_METHOD_CONTRACT; - FAULT_NOT_FATAL(); - DEBUG_ONLY_FUNCTION; - - BOOL ret = TRUE; - - EX_TRY - { - ret = AssignAppDomain(pAppDomain,raiseAssert); - } - EX_CATCH{} - EX_END_CATCH(SwallowAllExceptions); - - return ret; -} - -BOOL Object::AssignAppDomain(AppDomain *pAppDomain, BOOL raiseAssert) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - DEBUG_ONLY_FUNCTION; - - if (!g_pConfig->AppDomainLeaks()) - return TRUE; - - if (CheckAppDomain(pAppDomain)) - return TRUE; - - // - // App domain does not match; try to make this object agile - // - - if (IsTypeNeverAppDomainAgile()) - { - if (raiseAssert) - { - if (pAppDomain == NULL) - _ASSERTE(!"Attempt to reference a domain bound object from an agile location"); - else - _ASSERTE(!"Attempt to reference a domain bound object from a different domain"); - } - return FALSE; - } - else - { - // - // Make object agile - // - - if (! IsTypeAppDomainAgile() && ! SetFieldsAgile(raiseAssert)) - { - SetIsCheckedForAppDomainAgile(); - return FALSE; - } - - SetSyncBlockAppDomainAgile(); - - return TRUE; - } -} - -BOOL Object::AssignValueTypeAppDomain(MethodTable *pMT, void *base, AppDomain *pAppDomain, BOOL raiseAssert) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - DEBUG_ONLY_FUNCTION; - - if (!g_pConfig->AppDomainLeaks()) - return TRUE; - - if (pMT->GetClass()->IsAppDomainAgile()) - return TRUE; - - if (pAppDomain == NULL) - { - // - // Do not allow any object to be set to be agile unless we - // are compiling field access checking into the class. This - // will help guard against unintentional "agile" propagation - // as well. - // - - if (pMT->GetClass()->IsNeverAppDomainAgile()) - { - _ASSERTE(!"Attempt to reference a domain bound object from an agile location"); - return FALSE; - } - - return SetClassFieldsAgile(pMT, base, TRUE/*=baseIsVT*/, raiseAssert); - } - else - { - return ValidateClassFields(pMT, base, TRUE/*=baseIsVT*/, pAppDomain, raiseAssert); - } -} - -BOOL Object::SetFieldsAgile(BOOL raiseAssert, SetAppDomainAgilePendingTable *pTable) -{ - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - INJECT_FAULT(COMPlusThrowOM();); - DEBUG_ONLY; - } - CONTRACTL_END; - - BOOL result = TRUE; - - MethodTable *pMT= GetGCSafeMethodTable(); - - if (pMT->IsArray()) - { - switch (pMT->GetArrayElementType()) - { - case ELEMENT_TYPE_CLASS: - case ELEMENT_TYPE_ARRAY: - case ELEMENT_TYPE_SZARRAY: - { - PtrArray *pArray = (PtrArray *) this; - - DWORD n = pArray->GetNumComponents(); - OBJECTREF *p = (OBJECTREF *) - (((BYTE*)pArray) + ArrayBase::GetDataPtrOffset(GetGCSafeMethodTable())); - - for (DWORD i=0; i<n; i++) - { - if (!p[i]->SetAppDomainAgile(raiseAssert, pTable)) - result = FALSE; - } - - break; - } - case ELEMENT_TYPE_VALUETYPE: - { - ArrayBase *pArray = (ArrayBase *) this; - - MethodTable *pElemMT = pMT->GetApproxArrayElementTypeHandle().GetMethodTable(); - - BYTE *p = ((BYTE*)pArray) + ArrayBase::GetDataPtrOffset(GetGCSafeMethodTable()); - SIZE_T size = pArray->GetComponentSize(); - SIZE_T n = pArray->GetNumComponents(); - - for (SIZE_T i=0; i<n; i++) - if (!SetClassFieldsAgile(pElemMT, p + i*size, TRUE/*=baseIsVT*/, raiseAssert, pTable)) - result = FALSE; - - break; - } - - default: - _ASSERTE(!"Unexpected array type"); - } - } - else - { - if (pMT->GetClass()->IsNeverAppDomainAgile()) - { - _ASSERTE(!"Attempt to reference a domain bound object from an agile location"); - return FALSE; - } - - while (pMT != NULL && !pMT->GetClass()->IsTypesafeAppDomainAgile()) - { - if (!SetClassFieldsAgile(pMT, this, FALSE/*=baseIsVT*/, raiseAssert, pTable)) - result = FALSE; - - pMT = pMT->GetParentMethodTable(); - - if (pMT->GetClass()->IsNeverAppDomainAgile()) - { - _ASSERTE(!"Attempt to reference a domain bound object from an agile location"); - return FALSE; - } - } - } - - return result; -} - -BOOL Object::SetClassFieldsAgile(MethodTable *pMT, void *base, BOOL baseIsVT, BOOL raiseAssert, SetAppDomainAgilePendingTable *pTable) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - - BOOL result = TRUE; - - if (pMT->GetClass()->IsNeverAppDomainAgile()) - { - _ASSERTE(!"Attempt to reference a domain bound object from an agile location"); - return FALSE; - } - - // This type approximation is OK since we are only checking some layout information - // and all compatible instantiations share the same GC characteristics - ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS); - FieldDesc* pField; - - while ((pField = fdIterator.Next()) != NULL) - { - if (pField->IsDangerousAppDomainAgileField()) - { - if (pField->GetFieldType() == ELEMENT_TYPE_CLASS) - { - OBJECTREF ref; - - if (baseIsVT) - ref = *(OBJECTREF*) pField->GetAddressNoThrowNoGC(base); - else - ref = *(OBJECTREF*) pField->GetAddressGuaranteedInHeap(base); - - if (ref != 0 && !ref->IsAppDomainAgile()) - { - if (!ref->SetAppDomainAgile(raiseAssert, pTable)) - result = FALSE; - } - } - else if (pField->GetFieldType() == ELEMENT_TYPE_VALUETYPE) - { - // Be careful here - we may not have loaded a value - // type field of a class under prejit, and we don't - // want to trigger class loading here. - - TypeHandle th = pField->LookupFieldTypeHandle(); - if (!th.IsNull()) - { - void *nestedBase; - - if (baseIsVT) - nestedBase = pField->GetAddressNoThrowNoGC(base); - else - nestedBase = pField->GetAddressGuaranteedInHeap(base); - - if (!SetClassFieldsAgile(th.GetMethodTable(), - nestedBase, - TRUE/*=baseIsVT*/, - raiseAssert, - pTable)) - { - result = FALSE; - } - } - } - else - { - _ASSERTE(!"Bad field type"); - } - } - } - - return result; -} - -BOOL Object::ValidateAppDomain(AppDomain *pAppDomain) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - - - if (!g_pConfig->AppDomainLeaks()) - return TRUE; - - if (this == NULL) - return TRUE; - - if (CheckAppDomain()) - return ValidateAppDomainFields(pAppDomain); - - return AssignAppDomain(pAppDomain); -} - -BOOL Object::ValidateAppDomainFields(AppDomain *pAppDomain) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - - BOOL result = TRUE; - - MethodTable *pMT = GetGCSafeMethodTable(); - - while (pMT != NULL && !pMT->GetClass()->IsTypesafeAppDomainAgile()) - { - if (!ValidateClassFields(pMT, this, FALSE/*=baseIsVT*/, pAppDomain)) - result = FALSE; - - pMT = pMT->GetParentMethodTable(); - } - - return result; -} - -BOOL Object::ValidateValueTypeAppDomain(MethodTable *pMT, void *base, AppDomain *pAppDomain, BOOL raiseAssert) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - - if (!g_pConfig->AppDomainLeaks()) - return TRUE; - - if (pAppDomain == NULL) - { - if (pMT->GetClass()->IsTypesafeAppDomainAgile()) - return TRUE; - else if (pMT->GetClass()->IsNeverAppDomainAgile()) - { - if (raiseAssert) - _ASSERTE(!"Value type cannot be app domain agile"); - return FALSE; - } - } - - return ValidateClassFields(pMT, base, TRUE/*=baseIsVT*/, pAppDomain, raiseAssert); -} - -BOOL Object::ValidateClassFields(MethodTable *pMT, void *base, BOOL baseIsVT, AppDomain *pAppDomain, BOOL raiseAssert) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - - BOOL result = TRUE; - - // This type approximation is OK since we are only checking some layout information - // and all compatible instantiations share the same GC characteristics - ApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS); - FieldDesc* pField; - - while ((pField = fdIterator.Next()) != NULL) - { - if (!pMT->GetClass()->IsCheckAppDomainAgile() - || pField->IsDangerousAppDomainAgileField()) - { - if (pField->GetFieldType() == ELEMENT_TYPE_CLASS) - { - OBJECTREF ref; - - if (baseIsVT) - ref = ObjectToOBJECTREF(*(Object**) pField->GetAddressNoThrowNoGC(base)); - else - ref = ObjectToOBJECTREF(*(Object**) pField->GetAddressGuaranteedInHeap(base)); - - if (ref != 0 && !ref->AssignAppDomain(pAppDomain, raiseAssert)) - result = FALSE; - } - else if (pField->GetFieldType() == ELEMENT_TYPE_VALUETYPE) - { - // Be careful here - we may not have loaded a value - // type field of a class under prejit, and we don't - // want to trigger class loading here. - - TypeHandle th = pField->LookupFieldTypeHandle(); - if (!th.IsNull()) - { - void *nestedBase; - - if (baseIsVT) - nestedBase = pField->GetAddressNoThrowNoGC(base); - else - nestedBase = pField->GetAddressGuaranteedInHeap(base); - - if (!ValidateValueTypeAppDomain(th.GetMethodTable(), - nestedBase, - pAppDomain, - raiseAssert - )) - result = FALSE; - - } - } - } - } - - return result; -} - -#endif // CHECK_APP_DOMAIN_LEAKS - void Object::ValidatePromote(ScanContext *sc, DWORD flags) { STATIC_CONTRACT_NOTHROW; @@ -1313,30 +461,6 @@ void Object::ValidatePromote(ScanContext *sc, DWORD flags) #if defined (VERIFY_HEAP) Validate(); #endif - -#if CHECK_APP_DOMAIN_LEAKS - // Do app domain integrity checking here - if (g_pConfig->AppDomainLeaks()) - { - AppDomain *pDomain = GetAppDomain(); - -// This assert will incorrectly trip when -// InternalCrossContextCallback is on the stack. InternalCrossContextCallback -// intentionally passes an object across domains on the same thread. -#if 0 - if (flags & GC_CALL_CHECK_APP_DOMAIN) - _ASSERTE(TryAssignAppDomain(sc->pCurrentDomain)); -#endif - - if ((flags & GC_CALL_CHECK_APP_DOMAIN) - && pDomain != NULL - && !pDomain->ShouldHaveRoots() - && !TrySetAppDomainAgile(FALSE)) - { - _ASSERTE(!"Found GC object which should have been purged during app domain unload."); - } - } -#endif } void Object::ValidateHeap(Object *from, BOOL bDeep) @@ -1350,51 +474,6 @@ void Object::ValidateHeap(Object *from, BOOL bDeep) //since this is called in verify_heap, which will verfiy every object anyway Validate(bDeep, FALSE); #endif - -#if CHECK_APP_DOMAIN_LEAKS - // Do app domain integrity checking here - if (g_pConfig->AppDomainLeaks() && bDeep) - { - AppDomain *pDomain = from->GetAppDomain(); - - // - // Don't perform check if we're checking for agility, and the containing type is not - // marked checked agile - this will cover "proxy" type agility - // where cross references are allowed - // - - // Changed the GetMethodTable calls in this function to GetGCSafeMethodTable - // because GC could use the mark bit to simulate a mark and can have it set during - // verify heap (and would be cleared when verify heap is done). - // We'd get AV pretty soon anyway if it was truly mistakenly set. - if (pDomain != NULL || from->GetGCSafeMethodTable()->GetClass()->IsCheckAppDomainAgile()) - { - //special case:thread object is allowed to hold a context belonging to current domain - if (from->GetGCSafeMethodTable() == g_pThreadClass && - ( - false)) - { - if (((ThreadBaseObject *)from)->m_InternalThread) - _ASSERTE (CheckAppDomain (((ThreadBaseObject *)from)->m_InternalThread->GetDomain ())); - } - // special case: Overlapped has a field OverlappedData which may be moved to default domain - // during AD unload - else if (GetGCSafeMethodTable() == g_pOverlappedDataClass && - GetAppDomainIndex() == SystemDomain::System()->DefaultDomain()->GetIndex()) - { - } - else - { - TryAssignAppDomain(pDomain); - } - } - - if (pDomain != NULL - && !pDomain->ShouldHaveInstances() - && !TrySetAppDomainAgile(FALSE)) - _ASSERTE(!"Found GC object which should have been purged during app domain unload."); - } -#endif } void Object::SetOffsetObjectRef(DWORD dwOffset, size_t dwValue) @@ -1414,32 +493,6 @@ void Object::SetOffsetObjectRef(DWORD dwOffset, size_t dwValue) SetObjectReference( location, o, GetAppDomain() ); } -/******************************************************************/ -/* - * Write Barrier Helper - * - * Use this function to assign an object reference into - * another object. - * - * It will set the appropriate GC Write Barrier data - */ - -#if CHECK_APP_DOMAIN_LEAKS -void SetObjectReferenceChecked(OBJECTREF *dst,OBJECTREF ref,AppDomain *pAppDomain) -{ - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - STATIC_CONTRACT_MODE_COOPERATIVE; - STATIC_CONTRACT_CANNOT_TAKE_LOCK; - - DEBUG_ONLY_FUNCTION; - - ref->TryAssignAppDomain(pAppDomain); - return SetObjectReferenceUnchecked(dst,ref); -} -#endif - void SetObjectReferenceUnchecked(OBJECTREF *dst,OBJECTREF ref) { STATIC_CONTRACT_NOTHROW; @@ -1457,59 +510,6 @@ void SetObjectReferenceUnchecked(OBJECTREF *dst,OBJECTREF ref) #endif ErectWriteBarrier(dst, ref); } - -/******************************************************************/ - // copies src to dest worrying about write barriers. - // Note that it can work on normal objects (but not arrays) - // if dest, points just after the VTABLE. -#if CHECK_APP_DOMAIN_LEAKS -void CopyValueClassChecked(void* dest, void* src, MethodTable *pMT, AppDomain *pDomain) -{ - STATIC_CONTRACT_DEBUG_ONLY; - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - STATIC_CONTRACT_MODE_COOPERATIVE; - - DEBUG_ONLY_FUNCTION; - - FAULT_NOT_FATAL(); - EX_TRY - { - Object::AssignValueTypeAppDomain(pMT, src, pDomain); - } - EX_CATCH - { - } - EX_END_CATCH(SwallowAllExceptions); - CopyValueClassUnchecked(dest,src,pMT); -} - -// Copy value class into the argument specified by the argDest, performing an appdomain check first. -// The destOffset is nonzero when copying values into Nullable<T>, it is the offset -// of the T value inside of the Nullable<T> -void CopyValueClassArgChecked(ArgDestination *argDest, void* src, MethodTable *pMT, AppDomain *pDomain, int destOffset) -{ - STATIC_CONTRACT_DEBUG_ONLY; - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_FORBID_FAULT; - STATIC_CONTRACT_MODE_COOPERATIVE; - - DEBUG_ONLY_FUNCTION; - - FAULT_NOT_FATAL(); - EX_TRY - { - Object::AssignValueTypeAppDomain(pMT, src, pDomain); - } - EX_CATCH - { - } - EX_END_CATCH(SwallowAllExceptions); - CopyValueClassArgUnchecked(argDest, src, pMT, destOffset); -} -#endif void STDCALL CopyValueClassUnchecked(void* dest, void* src, MethodTable *pMT) { @@ -1771,19 +771,6 @@ VOID Object::ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncB lastTest = 6; -#if CHECK_APP_DOMAIN_LEAKS - // when it's not safe to verify the fields, it's not safe to verify AppDomain either - // because the process might try to access fields. - if (bDeep && g_pConfig->AppDomainLeaks()) - { - // - // Check to see that our domain is valid. This will assert if it has been unloaded. - // - SCAN_IGNORE_FAULT; - GetAppDomain(); - } -#endif - lastTest = 7; _ASSERTE(GCHeapUtilities::IsGCHeapInitialized()); diff --git a/src/vm/object.h b/src/vm/object.h index 8db3c17ffc..3ba892af0d 100644 --- a/src/vm/object.h +++ b/src/vm/object.h @@ -97,71 +97,6 @@ class ArgDestination; struct RCW; -#if CHECK_APP_DOMAIN_LEAKS - -class Object; - -class SetAppDomainAgilePendingTable -{ -public: - - SetAppDomainAgilePendingTable (); - ~SetAppDomainAgilePendingTable (); - - void PushReference (Object *pObject) - { - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - - PendingEntry entry; - entry.pObject = pObject; - - m_Stack.Push(entry); - } - - void PushParent (Object *pObject) - { - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - - PendingEntry entry; - entry.pObject = (Object*)((size_t)pObject | 1); - - m_Stack.Push(entry); - } - - Object *GetPendingObject (bool *pfReturnedToParent) - { - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_NOTRIGGER; - - if (!m_Stack.Count()) - return NULL; - - PendingEntry *pPending = m_Stack.Pop(); - - *pfReturnedToParent = pPending->fMarked != 0; - return (Object*)((size_t)pPending->pObject & ~1); - } - -private: - - union PendingEntry - { - Object *pObject; - - // Indicates whether the current thread set BIT_SBLK_AGILE_IN_PROGRESS - // on the object. Entries without this flag set are unexplored - // objects. - size_t fMarked:1; - }; - - CStackArray<PendingEntry> m_Stack; -}; - -#endif //CHECK_APP_DOMAIN_LEAKS - - // // The generational GC requires that every object be at least 12 bytes // in size. @@ -357,101 +292,6 @@ class Object void DEBUG_SetAppDomain(AppDomain *pDomain); #endif //_DEBUG - -#if CHECK_APP_DOMAIN_LEAKS - - // Mark object as app domain agile - BOOL SetAppDomainAgile(BOOL raiseAssert=TRUE, SetAppDomainAgilePendingTable *pTable = NULL); - BOOL TrySetAppDomainAgile(BOOL raiseAssert=TRUE); - - // Mark sync block as app domain agile - void SetSyncBlockAppDomainAgile(); - - // Check if object is app domain agile - BOOL IsAppDomainAgile(); - - // Check if object is app domain agile - BOOL IsAppDomainAgileRaw() - { - WRAPPER_NO_CONTRACT; - - SyncBlock *psb = PassiveGetSyncBlock(); - - return (psb && psb->IsAppDomainAgile()); - } - - BOOL IsCheckedForAppDomainAgile() - { - WRAPPER_NO_CONTRACT; - - SyncBlock *psb = PassiveGetSyncBlock(); - return (psb && psb->IsCheckedForAppDomainAgile()); - } - - void SetIsCheckedForAppDomainAgile() - { - WRAPPER_NO_CONTRACT; - - SyncBlock *psb = PassiveGetSyncBlock(); - if (psb) - psb->SetIsCheckedForAppDomainAgile(); - } - - // Check object to see if it is usable in the current domain - BOOL CheckAppDomain() { WRAPPER_NO_CONTRACT; return CheckAppDomain(::GetAppDomain()); } - - //Check object to see if it is usable in the given domain - BOOL CheckAppDomain(AppDomain *pDomain); - - // Check if the object's type is app domain agile - BOOL IsTypeAppDomainAgile(); - - // Check if the object's type is conditionally app domain agile - BOOL IsTypeCheckAppDomainAgile(); - - // Check if the object's type is naturally app domain agile - BOOL IsTypeTypesafeAppDomainAgile(); - - // Check if the object's type is possibly app domain agile - BOOL IsTypeNeverAppDomainAgile(); - - // Validate object & fields to see that it's usable from the current app domain - BOOL ValidateAppDomain() { WRAPPER_NO_CONTRACT; return ValidateAppDomain(::GetAppDomain()); } - - // Validate object & fields to see that it's usable from any app domain - BOOL ValidateAppDomainAgile() { WRAPPER_NO_CONTRACT; return ValidateAppDomain(NULL); } - - // Validate object & fields to see that it's usable from the given app domain (or null for agile) - BOOL ValidateAppDomain(AppDomain *pAppDomain); - - // Validate fields to see that they are usable from the object's app domain - // (or from any domain if the object is agile) - BOOL ValidateAppDomainFields() { WRAPPER_NO_CONTRACT; return ValidateAppDomainFields(GetAppDomain()); } - - // Validate fields to see that they are usable from the given app domain (or null for agile) - BOOL ValidateAppDomainFields(AppDomain *pAppDomain); - - // Validate a value type's fields to see that it's usable from the current app domain - static BOOL ValidateValueTypeAppDomain(MethodTable *pMT, void *base, BOOL raiseAssert = TRUE) - { WRAPPER_NO_CONTRACT; return ValidateValueTypeAppDomain(pMT, base, ::GetAppDomain(), raiseAssert); } - - // Validate a value type's fields to see that it's usable from any app domain - static BOOL ValidateValueTypeAppDomainAgile(MethodTable *pMT, void *base, BOOL raiseAssert = TRUE) - { WRAPPER_NO_CONTRACT; return ValidateValueTypeAppDomain(pMT, base, NULL, raiseAssert); } - - // Validate a value type's fields to see that it's usable from the given app domain (or null for agile) - static BOOL ValidateValueTypeAppDomain(MethodTable *pMT, void *base, AppDomain *pAppDomain, BOOL raiseAssert = TRUE); - - // Call when we are assigning this object to a dangerous field - // in an object in a given app domain (or agile if null) - BOOL AssignAppDomain(AppDomain *pAppDomain, BOOL raiseAssert = TRUE); - BOOL TryAssignAppDomain(AppDomain *pAppDomain, BOOL raiseAssert = TRUE); - - // Call when we are assigning to a dangerous value type field - // in an object in a given app domain (or agile if null) - static BOOL AssignValueTypeAppDomain(MethodTable *pMT, void *base, AppDomain *pAppDomain, BOOL raiseAssert = TRUE); - -#endif // CHECK_APP_DOMAIN_LEAKS // DO NOT ADD ANY ASSERTS TO THIS METHOD. // DO NOT USE THIS METHOD. @@ -672,15 +512,6 @@ class Object private: VOID ValidateInner(BOOL bDeep, BOOL bVerifyNextHeader, BOOL bVerifySyncBlock); -#if CHECK_APP_DOMAIN_LEAKS - friend class ObjHeader; - BOOL SetFieldsAgile(BOOL raiseAssert = TRUE, SetAppDomainAgilePendingTable *pTable = NULL); - static BOOL SetClassFieldsAgile(MethodTable *pMT, void *base, BOOL baseIsVT, BOOL raiseAssert = TRUE, SetAppDomainAgilePendingTable *pTable = NULL); - static BOOL ValidateClassFields(MethodTable *pMT, void *base, BOOL baseIsVT, AppDomain *pAppDomain, BOOL raiseAssert = TRUE); - BOOL SetAppDomainAgileWorker(BOOL raiseAssert, SetAppDomainAgilePendingTable *pTable); - BOOL ShouldCheckAppDomainAgile(BOOL raiseAssert, BOOL *pfResult); -#endif - #ifdef _DEBUG void AssertNotArray() { @@ -733,24 +564,10 @@ inline void InitValueClass(void *dest, MethodTable *pMT) // Initialize value class argument void InitValueClassArg(ArgDestination *argDest, MethodTable *pMT); -#if CHECK_APP_DOMAIN_LEAKS - -void SetObjectReferenceChecked(OBJECTREF *dst,OBJECTREF ref, AppDomain *pAppDomain); -void CopyValueClassChecked(void* dest, void* src, MethodTable *pMT, AppDomain *pAppDomain); -void CopyValueClassArgChecked(ArgDestination *argDest, void* src, MethodTable *pMT, AppDomain *pAppDomain, int destOffset); - -#define SetObjectReference(_d,_r,_a) SetObjectReferenceChecked(_d, _r, _a) -#define CopyValueClass(_d,_s,_m,_a) CopyValueClassChecked(_d,_s,_m,_a) -#define CopyValueClassArg(_d,_s,_m,_a,_o) CopyValueClassArgChecked(_d,_s,_m,_a,_o) - -#else - #define SetObjectReference(_d,_r,_a) SetObjectReferenceUnchecked(_d, _r) #define CopyValueClass(_d,_s,_m,_a) CopyValueClassUnchecked(_d,_s,_m) #define CopyValueClassArg(_d,_s,_m,_a,_o) CopyValueClassArgUnchecked(_d,_s,_m,_o) -#endif - #include <pshpack4.h> @@ -840,11 +657,7 @@ public: SIZE_T GetComponentSize() const { WRAPPER_NO_CONTRACT; MethodTable * pMT; -#if CHECK_APP_DOMAIN_LEAKS - pMT = GetGCSafeMethodTable(); -#else pMT = GetMethodTable(); -#endif //CHECK_APP_DOMAIN_LEAKS _ASSERTE(pMT->HasComponentSize()); return pMT->RawGetComponentSize(); } diff --git a/src/vm/olevariant.cpp b/src/vm/olevariant.cpp index 1ec6f70213..95c0b9b0cc 100644 --- a/src/vm/olevariant.cpp +++ b/src/vm/olevariant.cpp @@ -1721,10 +1721,6 @@ void OleVariant::MarshalInterfaceArrayOleToCom(void *oleArray, BASEARRAYREF *pCo BASEARRAYREF unprotectedArray = *pComArray; OBJECTREF *pCom = (OBJECTREF *) unprotectedArray->GetDataPtr(); -#if CHECK_APP_DOMAIN_LEAKS - AppDomain *pDomain = unprotectedArray->GetAppDomain(); -#endif // CHECK_APP_DOMAIN_LEAKS - OBJECTREF obj = NULL; GCPROTECT_BEGIN(obj) { @@ -1886,10 +1882,6 @@ void OleVariant::MarshalBSTRArrayOleToCom(void *oleArray, BASEARRAYREF *pComArra BASEARRAYREF unprotectedArray = *pComArray; STRINGREF *pCom = (STRINGREF *) unprotectedArray->GetDataPtr(); - -#if CHECK_APP_DOMAIN_LEAKS - AppDomain *pDomain = unprotectedArray->GetAppDomain(); -#endif // CHECK_APP_DOMAIN_LEAKS while (pOle < pOleEnd) { @@ -2104,10 +2096,6 @@ void OleVariant::MarshalLPWSTRArrayOleToCom(void *oleArray, BASEARRAYREF *pComAr BASEARRAYREF unprotectedArray = *pComArray; STRINGREF *pCom = (STRINGREF *) unprotectedArray->GetDataPtr(); - -#if CHECK_APP_DOMAIN_LEAKS - AppDomain *pDomain = unprotectedArray->GetAppDomain(); -#endif // CHECK_APP_DOMAIN_LEAKS while (pOle < pOleEnd) { @@ -2244,10 +2232,6 @@ void OleVariant::MarshalLPSTRArrayOleToCom(void *oleArray, BASEARRAYREF *pComArr BASEARRAYREF unprotectedArray = *pComArray; STRINGREF *pCom = (STRINGREF *) unprotectedArray->GetDataPtr(); - -#if CHECK_APP_DOMAIN_LEAKS - AppDomain *pDomain = unprotectedArray->GetAppDomain(); -#endif // CHECK_APP_DOMAIN_LEAKS while (pOle < pOleEnd) { diff --git a/src/vm/syncblk.cpp b/src/vm/syncblk.cpp index 8f6f5448f9..11151a32c5 100644 --- a/src/vm/syncblk.cpp +++ b/src/vm/syncblk.cpp @@ -1724,46 +1724,6 @@ void SyncBlockCache::VerifySyncTableEntry() #endif // VERIFY_HEAP -#if CHECK_APP_DOMAIN_LEAKS -void SyncBlockCache::CheckForUnloadedInstances(ADIndex unloadingIndex) -{ - CONTRACTL - { - INSTANCE_CHECK; - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - // Can only do in leak mode because agile objects will be in the domain with - // their index set to their creating domain and check will fail. - if (! g_pConfig->AppDomainLeaks()) - return; - - for (DWORD nb = 1; nb < m_FreeSyncTableIndex; nb++) - { - SyncTableEntry *pEntry = &SyncTableEntry::GetSyncTableEntry()[nb]; - Object *oref = (Object *) pEntry->m_Object; - if (((size_t) oref & 1) != 0) - continue; - - ADIndex idx; - if (oref) - idx = pEntry->m_Object->GetHeader()->GetRawAppDomainIndex(); - if (! idx.m_dwIndex && pEntry->m_SyncBlock) - idx = pEntry->m_SyncBlock->GetAppDomainIndex(); - // if the following assert fires, someobody is holding a reference to an object in an unloaded appdomain - if (idx == unloadingIndex) - { - // object must be agile to have survived the unload. If can't make it agile, that's a bug - if (!oref->TrySetAppDomainAgile(TRUE)) - _ASSERTE(!"Detected instance of unloaded appdomain that survived GC\n"); - } - } -} -#endif - #ifdef _DEBUG void DumpSyncBlockCache() @@ -2580,25 +2540,8 @@ BOOL ObjHeader::Validate (BOOL bVerifySyncBlkIndex) } else { -#if CHECK_APP_DOMAIN_LEAKS - if (bVerifyMore) - { - if (bits & BIT_SBLK_AGILE_IN_PROGRESS) - { - BOOL fResult; - ASSERT_AND_CHECK ( - //BIT_SBLK_AGILE_IN_PROGRESS is set only if the object needs to check appdomain agile - obj->ShouldCheckAppDomainAgile(FALSE, &fResult) - //before BIT_SBLK_AGILE_IN_PROGRESS is cleared, the object might already be marked as agile - ||(obj->PassiveGetSyncBlock () && obj->PassiveGetSyncBlock ()->IsAppDomainAgile ()) - ||(obj->PassiveGetSyncBlock () && obj->PassiveGetSyncBlock ()->IsCheckedForAppDomainAgile ()) - ); - } - } -#else //CHECK_APP_DOMAIN_LEAKS //BIT_SBLK_AGILE_IN_PROGRESS is set only in debug build ASSERT_AND_CHECK (!(bits & BIT_SBLK_AGILE_IN_PROGRESS)); -#endif //CHECK_APP_DOMAIN_LEAKS if (bits & BIT_SBLK_FINALIZER_RUN) { ASSERT_AND_CHECK (obj->GetGCSafeMethodTable ()->HasFinalizer ()); diff --git a/src/vm/syncblk.h b/src/vm/syncblk.h index 212a726eb5..ab32fc76aa 100644 --- a/src/vm/syncblk.h +++ b/src/vm/syncblk.h @@ -844,14 +844,6 @@ class SyncBlock // can never be 0. ObjectNative::GetHashCode in COMObject.cpp makes sure to enforce this. DWORD m_dwHashCode; -#if CHECK_APP_DOMAIN_LEAKS - DWORD m_dwFlags; - - enum { - IsObjectAppDomainAgile = 1, - IsObjectCheckedForAppDomainAgile = 2, - }; -#endif // In some early version of VB when there were no arrays developers used to use BSTR as arrays // The way this was done was by adding a trail byte at the end of the BSTR // To support this scenario, we need to use the sync block for this special case and @@ -866,9 +858,6 @@ class SyncBlock , m_pEnCInfo(PTR_NULL) #endif // EnC_SUPPORTED , m_dwHashCode(0) -#if CHECK_APP_DOMAIN_LEAKS - , m_dwFlags(0) -#endif , m_BSTRTrailByte(0) { LIMITED_METHOD_CONTRACT; @@ -1088,34 +1077,6 @@ class SyncBlock SyncBlockPrecious = 0x80000000, }; -#if CHECK_APP_DOMAIN_LEAKS - BOOL IsAppDomainAgile() - { - LIMITED_METHOD_CONTRACT; - return m_dwFlags & IsObjectAppDomainAgile; - } - void SetIsAppDomainAgile() - { - LIMITED_METHOD_CONTRACT; - m_dwFlags |= IsObjectAppDomainAgile; - } - void UnsetIsAppDomainAgile() - { - LIMITED_METHOD_CONTRACT; - m_dwFlags = m_dwFlags & ~IsObjectAppDomainAgile; - } - BOOL IsCheckedForAppDomainAgile() - { - LIMITED_METHOD_CONTRACT; - return m_dwFlags & IsObjectCheckedForAppDomainAgile; - } - void SetIsCheckedForAppDomainAgile() - { - LIMITED_METHOD_CONTRACT; - m_dwFlags |= IsObjectCheckedForAppDomainAgile; - } -#endif //CHECK_APP_DOMAIN_LEAKS - BOOL HasCOMBstrTrailByte() { LIMITED_METHOD_CONTRACT; @@ -1315,9 +1276,6 @@ class SyncBlockCache }; friend class LockHolder; -#if CHECK_APP_DOMAIN_LEAKS - void CheckForUnloadedInstances(ADIndex unloadingIndex); -#endif #ifdef _DEBUG friend void DumpSyncBlockCache(); #endif diff --git a/src/vm/typehandle.cpp b/src/vm/typehandle.cpp index 9e8afba82f..c8c6362dd6 100644 --- a/src/vm/typehandle.cpp +++ b/src/vm/typehandle.cpp @@ -1442,7 +1442,7 @@ OBJECTREF TypeHandle::GetManagedClassObjectFast() const #endif // #ifndef DACCESS_COMPILE -#if defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#if defined(_DEBUG) BOOL TypeHandle::IsAppDomainAgile() const { @@ -1534,7 +1534,7 @@ BOOL TypeHandle::IsArrayOfElementsCheckAppDomainAgile() const } } -#endif // defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#endif // defined(_DEBUG) BOOL TypeHandle::IsByRef() const diff --git a/src/vm/typehandle.h b/src/vm/typehandle.h index cec772e3be..5cb9eaa7a6 100644 --- a/src/vm/typehandle.h +++ b/src/vm/typehandle.h @@ -574,7 +574,7 @@ public: INDEBUGIMPL(BOOL Verify();) // DEBUGGING Make certain this is a valid type handle -#if defined(CHECK_APP_DOMAIN_LEAKS) || defined(_DEBUG) +#if defined(_DEBUG) BOOL IsAppDomainAgile() const; BOOL IsCheckAppDomainAgile() const; |