summaryrefslogtreecommitdiff
path: root/src/vm/contexts.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/contexts.cpp')
-rw-r--r--src/vm/contexts.cpp911
1 files changed, 0 insertions, 911 deletions
diff --git a/src/vm/contexts.cpp b/src/vm/contexts.cpp
index eb957570ea..47cc81813f 100644
--- a/src/vm/contexts.cpp
+++ b/src/vm/contexts.cpp
@@ -11,917 +11,6 @@
#include "common.h"
-#ifdef FEATURE_REMOTING
-
-#include "context.h"
-#include "excep.h"
-#include "field.h"
-#include "remoting.h"
-#include "perfcounters.h"
-#include "specialstatics.h"
-#include "appdomain.inl"
-
-#ifdef FEATURE_COMINTEROP
-#include "runtimecallablewrapper.h"
-#endif // FEATURE_COMINTEROP
-
-#ifndef DACCESS_COMPILE
-
-#define CONTEXT_SIGNATURE (0x2b585443) // CTX+
-#define CONTEXT_DESTROYED (0x2d585443) // CTX-
-
-// Lock for safe operations
-CrstStatic Context::s_ContextCrst;
-
-
-Context::Context(AppDomain *pDomain)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pDomain));
- }
- CONTRACTL_END;
-
- m_pDomain = pDomain;
- m_Signature = CONTEXT_SIGNATURE;
-
- // This needs to be a LongWeakHandle since we want to be able
- // to run finalizers on Proxies while the Context itself
- // unreachable. When running the finalizer we will have to
- // transition into the context like a regular remote call.
- // If this is a short weak handle, it ceases being updated
- // as soon as the context is unreachable. By making it a strong
- // handle, it is updated till the context::finalize is run.
-
- m_ExposedObjectHandle = pDomain->CreateLongWeakHandle(NULL);
-
- // Set the pointers to the static data storage
- m_pUnsharedStaticData = NULL;
- m_pSharedStaticData = NULL;
-
- COUNTER_ONLY(GetPerfCounters().m_Context.cContexts++);
-}
-
-Context::~Context()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- BOOL fADUnloaded = m_pDomain->NoAccessToHandleTable();
- if (!fADUnloaded)
- {
- DestroyLongWeakHandle(m_ExposedObjectHandle);
- }
-
- m_pDomain = NULL;
- m_Signature = CONTEXT_DESTROYED;
-
- // Cleanup the static data storage
- if(m_pUnsharedStaticData)
- {
- for(WORD i = 0; i < m_pUnsharedStaticData->cElem; i++)
- {
- delete [] (BYTE *) (m_pUnsharedStaticData->dataPtr[i]);
- }
- delete [] m_pUnsharedStaticData;
- m_pUnsharedStaticData = NULL;
- }
-
- if(m_pSharedStaticData)
- {
- for(WORD i = 0; i < m_pSharedStaticData->cElem; i++)
- {
- delete [] (BYTE *) (m_pSharedStaticData->dataPtr[i]);
- }
- delete [] m_pSharedStaticData;
- m_pSharedStaticData = NULL;
- }
-
- // Destroy pinning handles associated with this context
- ObjectHandleList::NodeType* pHandleNode;
- while ((pHandleNode = m_PinnedContextStatics.UnlinkHead() ) != NULL)
- {
- if (!fADUnloaded)
- {
- DestroyPinningHandle(pHandleNode->data);
- }
- delete pHandleNode;
- }
-
- COUNTER_ONLY(GetPerfCounters().m_Context.cContexts--);
-}
-
-Context* Context::CreateNewContext(AppDomain *pDomain)
-{
- CONTRACT (Context*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pDomain));
- }
- CONTRACT_END;
-
- Context *p = new Context(pDomain);
- RETURN p;
-}
-
-void Context::Initialize()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- // Initialize the context critical section
- s_ContextCrst.Init(CrstContexts, (CrstFlags)(CRST_REENTRANCY|CRST_HOST_BREAKABLE));
-}
-
-BOOL Context::ValidateContext(Context *pCtx)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SO_TOLERANT;
- PRECONDITION(CheckPointer(pCtx));
- }
- CONTRACTL_END;
-
- BOOL bRet = FALSE;
-
- EX_TRY
- {
- if (pCtx->m_Signature == CONTEXT_SIGNATURE)
- bRet = TRUE;
- }
- EX_CATCH
- {
- // Swallow exceptions - if not a valid ctx, just return false.
- }
- EX_END_CATCH(RethrowTerminalExceptions);
-
- return bRet;
-}
-
-// if the object we are creating is a proxy to another appdomain, want to create the wrapper for the
-// new object in the appdomain of the proxy target
-Context* Context::GetExecutionContext(OBJECTREF pObj)
-{
- CONTRACT (Context*)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- PRECONDITION(pObj != NULL);
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- }
- CONTRACT_END;
-
- Context *pContext = NULL;
- if (pObj->IsTransparentProxy())
- pContext = CRemotingServices::GetServerContextForProxy(pObj);
- if (pContext == NULL)
- pContext = GetAppDomain()->GetDefaultContext();
-
- RETURN pContext;
-}
-
-OBJECTREF Context::GetExposedObject()
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- }
- CONTRACTL_END;
-
- if (ObjectFromHandle(m_ExposedObjectHandle) == NULL)
- {
- // This call should fault in the managed context for the thread
- MethodDescCallSite getCurrentContext(METHOD__THREAD__GET_CURRENT_CONTEXT);
- CONTEXTBASEREF ctx = (CONTEXTBASEREF) getCurrentContext.Call_RetOBJECTREF((ARG_SLOT*)NULL);
-
- GCPROTECT_BEGIN(ctx);
- {
- // Take a lock to make sure that only one thread creates the object.
- // This locking may be too severe!
- CrstHolder ch(&s_ContextCrst);
-
- // Check to see if another thread has not already created the exposed object.
- if (ObjectFromHandle(m_ExposedObjectHandle) == NULL)
- {
- // Keep a weak reference to the exposed object.
- StoreObjectInHandle(m_ExposedObjectHandle, (OBJECTREF) ctx);
-
- ctx->SetInternalContext(this);
- }
- }
- GCPROTECT_END();
-
- }
- return ObjectFromHandle(m_ExposedObjectHandle);
-}
-
-void Context::SetExposedObject(OBJECTREF exposed)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(exposed != NULL);
- PRECONDITION(ObjectFromHandle(m_ExposedObjectHandle) == NULL);
- }
- CONTRACTL_END;
-
- StoreObjectInHandle(m_ExposedObjectHandle, exposed);
-}
-
-// This is called by EE to transition into a context(possibly in
-// another appdomain) and execute the method Context::ExecuteCallBack
-// with the private data provided to this method
-void Context::RequestCallBack(ADID appDomainID, Context* targetCtxID, void* privateData)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(targetCtxID));
- PRECONDITION(CheckPointer(privateData));
- PRECONDITION(ValidateContext((Context*)targetCtxID));
- }
- CONTRACTL_END;
- // a warning: don't touch targetCtxID until you verified appDomainID,
- // unless the latter is CURRENT_APPDOMAIN_ID
-
- // Get the current context of the thread. This is assumed as
- // the context where the request originated
- Context *pCurrCtx;
- pCurrCtx = GetCurrentContext();
-
- // Check that the target context is not the same (presumably the caller has checked for it).
- _ASSERTE(pCurrCtx != targetCtxID);
-
- // Check if we might be going to a context in another appDomain.
- ADID targetDomainID;
-
- if (appDomainID == CURRENT_APPDOMAIN_ID)
- {
- targetDomainID = (ADID)0;
- _ASSERTE(targetCtxID->GetDomain()==::GetAppDomain());
- }
- else
- {
- targetDomainID=appDomainID;
-#ifdef _DEBUG
- AppDomainFromIDHolder ad(appDomainID, FALSE);
- if (!ad.IsUnloaded())
- _ASSERTE(targetCtxID->GetDomain()->GetId()==appDomainID);
-#endif
- }
-
- // we need to be co-operative mode for jitting
- GCX_COOP();
-
- MethodDescCallSite callback(METHOD__CONTEXT__CALLBACK);
-
- ARG_SLOT args[3];
- args[0] = PtrToArgSlot(targetCtxID);
- args[1] = PtrToArgSlot(privateData);
- args[2] = (ARG_SLOT) (size_t)targetDomainID.m_dwId;
-
- callback.Call(args);
-}
-
-/*** Definitions of callback executions for the various callbacks that are known to EE ***/
-
-// Callback for waits on waithandle
-void Context::ExecuteWaitCallback(WaitArgs* waitArgs)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(waitArgs));
- }
- CONTRACTL_END;
-
- Thread* pCurThread = GetThread();
- _ASSERTE(pCurThread != NULL);
-
- // DoAppropriateWait switches to preemptive GC before entering the wait
- *(waitArgs->pResult) = pCurThread->DoAppropriateWait( waitArgs->numWaiters,
- waitArgs->waitHandles,
- waitArgs->waitAll,
- waitArgs->millis,
- waitArgs->alertable?WaitMode_Alertable:WaitMode_None);
-}
-
-// Callback for monitor wait on objects
-void Context::ExecuteMonitorWaitCallback(MonitorWaitArgs* waitArgs)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(waitArgs));
- }
- CONTRACTL_END;
-
- Thread* pCurThread = GetThread();
- _ASSERTE(pCurThread != NULL);
-
- GCX_PREEMP();
-
- *(waitArgs->pResult) = pCurThread->Block(waitArgs->millis,
- waitArgs->syncState);
-}
-
-// Callback for signalandwait on waithandles
-void Context::ExecuteSignalAndWaitCallback(SignalAndWaitArgs* signalAndWaitArgs)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(signalAndWaitArgs));
- }
- CONTRACTL_END;
-
- Thread* pCurThread = GetThread();
- _ASSERTE(pCurThread != NULL);
-
- // DoAppropriateWait switches to preemptive GC before entering the wait
- *(signalAndWaitArgs->pResult) = pCurThread->DoSignalAndWait( signalAndWaitArgs->waitHandles,
- signalAndWaitArgs->millis,
- signalAndWaitArgs->alertable);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: Context::GetStaticFieldAddress private
-//
-// Synopsis: Get the address of the field relative to the current context.
-// If an address has not been assigned yet then create one.
-//
-
-//
-//+----------------------------------------------------------------------------
-LPVOID Context::GetStaticFieldAddress(FieldDesc *pFD)
-{
- CONTRACT (LPVOID)
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pFD));
- PRECONDITION(!s_ContextCrst.OwnedByCurrentThread());
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- LPVOID pvAddress = NULL;
- Context* pCtx = NULL;
- // for static field the MethodTable is exact even for generic classes
- MethodTable* pMT = pFD->GetEnclosingMethodTable();
- BOOL fIsShared = pMT->IsDomainNeutral();
- DWORD dwClassOffset = pMT->GetContextStaticsOffset();
- DWORD currElem = 0;
- STATIC_DATA* pData;
-
- // NOTE: if you change this method, you must also change
- // GetStaticFieldAddrNoCreate below.
-
- if (dwClassOffset == (DWORD)-1)
- {
- dwClassOffset = pMT->AllocateContextStaticsOffset();
- }
-
- // Retrieve the current context
- pCtx = GetCurrentContext();
- _ASSERTE(NULL != pCtx);
-
- // Acquire the context lock before accessing the static data pointer
- {
- CrstHolder ch(&s_ContextCrst);
-
- if(!fIsShared)
- pData = pCtx->m_pUnsharedStaticData;
- else
- pData = pCtx->m_pSharedStaticData;
-
- if(NULL != pData)
- currElem = pData->cElem;
-
- // Check whether we have allocated space for storing a pointer to
- // this class' context static store
- if(dwClassOffset >= currElem)
- {
- // Allocate space for storing pointers
- DWORD dwNewElem = (currElem == 0 ? 4 : currElem*2);
-
- // Ensure that we grow to a size larger than the index we intend to use
- while (dwNewElem <= dwClassOffset)
- dwNewElem = 2*dwNewElem;
-
- STATIC_DATA *pNew = (STATIC_DATA *)new BYTE[sizeof(STATIC_DATA) + dwNewElem*sizeof(LPVOID)];
-
- // Set the new count.
- pNew->cElem = dwNewElem;
-
- if(NULL != pData)
- {
- // Copy the old data into the new data
- memcpy(&pNew->dataPtr[0], &pData->dataPtr[0], currElem*sizeof(LPVOID));
-
- // Delete the old data
- delete [] (BYTE*) pData;
- }
-
- // Zero init any new elements.
- ZeroMemory(&pNew->dataPtr[currElem], (dwNewElem - currElem)* sizeof(LPVOID));
-
- // Update the locals
- pData = pNew;
-
- // Reset the pointers in the context object to point to the
- // new memory
- if(!fIsShared)
- pCtx->m_pUnsharedStaticData = pData;
- else
- pCtx->m_pSharedStaticData = pData;
- }
-
- _ASSERTE(NULL != pData);
-
- // Check whether we have to allocate space for
- // the context local statics of this class
- if(NULL == pData->dataPtr[dwClassOffset])
- {
- DWORD dwSize = pMT->GetContextStaticsSize();
-
- // Allocate memory for context static fields
- LPBYTE pFields = new BYTE[dwSize];
-
- // Initialize the memory allocated for the fields
- ZeroMemory(pFields, dwSize);
-
- pData->dataPtr[dwClassOffset] = pFields;
- }
-
- _ASSERTE(NULL != pData->dataPtr[dwClassOffset]);
-
- pvAddress = (LPVOID)((LPBYTE)pData->dataPtr[dwClassOffset] + pFD->GetOffset());
-
- // For object and value class fields we have to allocate storage in the
- // __StaticContainer class in the managed heap
- if(pFD->IsObjRef() || pFD->IsByValue())
- {
- // in this case *pvAddress == bucket|index
- int *pSlot = (int*)pvAddress;
- pvAddress = NULL;
- pCtx->GetStaticFieldAddressSpecial(pFD, pMT, pSlot, &pvAddress);
-
- if (pFD->IsByValue())
- {
- _ASSERTE(pvAddress != NULL);
- pvAddress = (*((OBJECTREF*)pvAddress))->GetData();
- }
- // ************************************************
- // ************** WARNING *************************
- // Do not provoke GC from here to the point JIT gets
- // pvAddress back
- // ************************************************
- _ASSERTE(*pSlot > 0);
- }
- }
-
- RETURN pvAddress;
-}
-
-
-//+----------------------------------------------------------------------------
-//
-// Method: Context::GetStaticFieldAddressSpecial private
-//
-// Synopsis: Allocate an entry in the __StaticContainer class in the
-// managed heap for static objects and value classes
-//
-
-//
-//+----------------------------------------------------------------------------
-
-// NOTE: At one point we used to allocate these in the long lived handle table
-// which is per-appdomain. However, that causes them to get rooted and not
-// cleaned up until the appdomain gets unloaded. This is not very desirable
-// since a context static object may hold a reference to the context itself or
-// to a proxy in the context causing a whole lot of garbage to float around.
-// Now (2/13/01) these are allocated from a managed structure rooted in each
-// managed context.
-
-void Context::GetStaticFieldAddressSpecial(FieldDesc *pFD, MethodTable *pMT, int *pSlot, LPVOID *ppvAddress)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_COOPERATIVE;
- INJECT_FAULT(COMPlusThrowOM());
- PRECONDITION(CheckPointer(pFD));
- PRECONDITION(CheckPointer(pMT));
- PRECONDITION(CheckPointer(pSlot));
- PRECONDITION(CheckPointer(ppvAddress));
- }
- CONTRACTL_END;
-
- OBJECTREF *pObjRef = NULL;
- BOOL bNewSlot = (*pSlot == 0);
-
- if (bNewSlot)
- {
- // ! this line will trigger a GC, don't move it down
- // ! without protecting the args[] and other OBJECTREFS
- OBJECTREF orThis = GetExposedObject();;
- GCPROTECT_BEGIN(orThis);
-
- MethodDescCallSite reserveSlot(METHOD__CONTEXT__RESERVE_SLOT, &orThis);
-
- // We need to assign a location for this static field.
- // Call the managed helper
- ARG_SLOT args[1] =
- {
- ObjToArgSlot(orThis)
- };
-
- // The managed ReserveSlot methods counts on this!
- _ASSERTE(s_ContextCrst.OwnedByCurrentThread());
- _ASSERTE(args[0] != 0);
-
- *pSlot = reserveSlot.Call_RetI4(args);
-
- _ASSERTE(*pSlot>0);
-
- GCPROTECT_END();
-
-
- // to a boxed version of the value class.This allows the standard GC
- // algorithm to take care of internal pointers in the value class.
- if (pFD->IsByValue())
- {
- // Extract the type of the field
- TypeHandle th = pFD->GetFieldTypeHandleThrowing();
-
- OBJECTHANDLE oh;
- OBJECTREF obj = MethodTable::AllocateStaticBox(th.GetMethodTable(), pMT->HasFixedAddressVTStatics(), &oh);
- pObjRef = (OBJECTREF*)CalculateAddressForManagedStatic(*pSlot);
-
- if (oh != NULL)
- {
- ObjectHandleList::NodeType* pNewNode = new ObjectHandleList::NodeType(oh);
- m_PinnedContextStatics.LinkHead(pNewNode);
- }
-
- SetObjectReference( pObjRef, obj, GetAppDomain() );
- }
- else
- {
- pObjRef = (OBJECTREF*)CalculateAddressForManagedStatic(*pSlot);
- }
- }
- else
- {
- // If the field already has a location assigned we go through here
- pObjRef = (OBJECTREF*)CalculateAddressForManagedStatic(*pSlot);
- }
-
- *(ULONG_PTR *)ppvAddress = (ULONG_PTR)pObjRef;
-}
-
-// This is called by the managed context constructor
-FCIMPL2(void, Context::SetupInternalContext, ContextBaseObject* pThisUNSAFE, CLR_BOOL bDefault)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pThisUNSAFE != NULL);
- PRECONDITION(pThisUNSAFE->m_internalContext == NULL);
- }
- CONTRACTL_END;
-
- CONTEXTBASEREF pThis = (CONTEXTBASEREF) pThisUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(pThis);
-
- Context *pCtx;
-
- if (bDefault)
- {
- // We have to hook this up with the internal default
- // context for the current appDomain
- pCtx = GetThread()->GetDomain()->GetDefaultContext();
- }
- else
- {
- // Create the unmanaged backing context object
- pCtx = Context::CreateNewContext(GetThread()->GetDomain());
- }
-
- // Set the managed & unmanaged objects to point at each other.
- pThis->SetInternalContext(pCtx);
- pCtx->SetExposedObject((OBJECTREF)pThis);
-
- // Set the AppDomain field in the Managed context object
- pThis->SetExposedDomain(GetThread()->GetDomain()->GetExposedObject());
-
- if(bDefault)
- ((APPDOMAINREF)GetThread()->GetDomain()->GetExposedObject())->SetDefaultContext(pThis);
-
- COUNTER_ONLY(GetPerfCounters().m_Context.cContexts++);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-// This is called by the managed context finalizer
-FCIMPL1(void, Context::CleanupInternalContext, ContextBaseObject* pThisUNSAFE)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(pThisUNSAFE != NULL);
- }
- CONTRACTL_END;
-
- CONTEXTBASEREF pThis = (CONTEXTBASEREF) pThisUNSAFE;
- HELPER_METHOD_FRAME_BEGIN_1(pThis);
-
- CONTEXTBASEREF refCtx = pThis;
-
- Context *pCtx = refCtx->m_internalContext;
- _ASSERTE(pCtx != NULL);
-
- if (ValidateContext(pCtx))
- {
- LOG((LF_APPDOMAIN, LL_INFO1000, "Context::CleanupInternalContext: %8.8x, %8.8x\n", OBJECTREFToObject(refCtx), pCtx));
- Context::FreeContext(pCtx);
- }
-
- COUNTER_ONLY(GetPerfCounters().m_Context.cContexts--);
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-// This is where a call back request made by EE in Context::RequestCallBack
-// actually gets "executed".
-// At this point we have done a real context transition from the threads
-// context when RequestCallBack was called to the destination context.
-FCIMPL1(void, Context::ExecuteCallBack, LPVOID privateData)
-{
- CONTRACTL
- {
- FCALL_CHECK;
- PRECONDITION(CheckPointer(privateData));
- }
- CONTRACTL_END;
-
- HELPER_METHOD_FRAME_BEGIN_0();
-
- switch (((CallBackInfo*) privateData)->callbackId)
- {
- case Wait_callback:
- {
- WaitArgs* waitArgs;
- waitArgs = (WaitArgs*) ((CallBackInfo*) privateData)->callbackData;
- ExecuteWaitCallback(waitArgs);
- break;
- }
-
- case MonitorWait_callback:
- {
- MonitorWaitArgs* waitArgs;
- waitArgs = (MonitorWaitArgs*) ((CallBackInfo*) privateData)->callbackData;
- ExecuteMonitorWaitCallback(waitArgs);
- break;
- }
-
- case ADTransition_callback:
- {
- ADCallBackArgs* pCallArgs = (ADCallBackArgs*)(((CallBackInfo*) privateData)->callbackData);
- pCallArgs->pTarget(pCallArgs->pArguments);
- break;
- }
-
- case SignalAndWait_callback:
- {
- SignalAndWaitArgs* signalAndWaitArgs;
- signalAndWaitArgs = (SignalAndWaitArgs*)((CallBackInfo*)privateData)->callbackData;
- ExecuteSignalAndWaitCallback(signalAndWaitArgs);
- break;
- }
- // Add other callback types here
- default:
- _ASSERTE(!"Invalid callback type");
- break;
- }
-
- // This is EE's entry point to do whatever it wanted to do in
- // the targetContext. This will return back into the managed
- // world and transition back into the original context.
-
- HELPER_METHOD_FRAME_END();
-}
-FCIMPLEND
-
-
-
-#ifdef ENABLE_PERF_COUNTERS
-
-FCIMPL0(LPVOID, GetPrivateContextsPerfCountersEx)
-{
- FCALL_CONTRACT;
-
- return (LPVOID)GetPrivateContextsPerfCounters();
-}
-FCIMPLEND
-
-
-#else
-FCIMPL0(LPVOID, GetPrivateContextsPerfCountersEx)
-{
- FCALL_CONTRACT;
-
- return NULL;
-}
-FCIMPLEND
-
-#endif // ENABLE_PERF_COUNTERS
-
-#endif // DACCESS_COMPILE
-
-// This will NOT create the exposed object if there isn't one!
-OBJECTREF Context::GetExposedObjectRaw()
-{
- WRAPPER_NO_CONTRACT;
-
- return ObjectFromHandle(m_ExposedObjectHandle);
-}
-
-
-PTR_Object Context::GetExposedObjectRawUnchecked()
-{
- LIMITED_METHOD_CONTRACT;
-
- return *PTR_PTR_Object(m_ExposedObjectHandle);
-}
-
-PTR_PTR_Object Context::GetExposedObjectRawUncheckedPtr()
-{
- LIMITED_METHOD_CONTRACT;
-
- return PTR_PTR_Object(m_ExposedObjectHandle);
-}
-
-//+----------------------------------------------------------------------------
-//
-// Method: Context::GetStaticFieldAddrNoCreate private
-//
-// Synopsis: Get the address of the field relative to the context given a thread.
-// If an address has not been assigned, return NULL.
-// No creating is allowed.
-//
-
-//
-//+----------------------------------------------------------------------------
-PTR_VOID Context::GetStaticFieldAddrNoCreate(FieldDesc *pFD)
-{
- CONTRACT (PTR_VOID)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(CheckPointer(pFD));
- POSTCONDITION(CheckPointer(RETVAL, NULL_OK));
- SUPPORTS_DAC;
- }
- CONTRACT_END;
-
- PTR_VOID pvAddress = NULL;
- // for static field the MethodTable is exact even for generic classes
- MethodTable* pMT = pFD->GetEnclosingMethodTable();
- BOOL fIsShared = pMT->IsDomainNeutral();
- DWORD dwClassOffset = pMT->GetContextStaticsOffset();
- DWORD currElem = 0;
- STATIC_DATA* pData;
-
- if (dwClassOffset == (DWORD)-1)
- RETURN NULL;
-
- if(!fIsShared)
- pData = m_pUnsharedStaticData;
- else
- pData = m_pSharedStaticData;
-
- if (NULL == pData)
- RETURN NULL;
-
- currElem = pData->cElem;
-
- // Check whether we have allocated space for storing a pointer to
- // this class' context static store
- if(dwClassOffset >= currElem || pData->dataPtr[dwClassOffset] == NULL)
- RETURN NULL;
-
- _ASSERTE(pData->dataPtr[dwClassOffset] != NULL);
-
- // We have allocated static storage for this data
- // Just return the address by getting the offset into the data
- pvAddress = PTR_VOID(dac_cast<PTR_BYTE>(pData->dataPtr[dwClassOffset]) + pFD->GetOffset());
-
- if(pFD->IsObjRef() || pFD->IsByValue())
- {
- if (*dac_cast<PTR_BYTE>(pvAddress) == NULL)
- {
- pvAddress = NULL;
- LOG((LF_SYNC, LL_ALWAYS, "dbgr: pvAddress = NULL"));
- }
- else
- {
- pvAddress = CalculateAddressForManagedStatic(*(PTR_int(pvAddress)));
- LOG((LF_SYNC, LL_ALWAYS, "dbgr: pvAddress = %lx", pvAddress));
- if (pFD->IsByValue())
- {
- _ASSERTE(pvAddress != NULL);
- pvAddress = (*(PTR_OBJECTREF(pvAddress)))->GetData();
- }
- }
- }
-
- RETURN pvAddress;
-}
-
-
-// This is used for context relative statics that are object refs
-// These are stored in a structure in the managed context. The first
-// time over an index and a bucket are determined and subsequently
-// remembered in the location for the field in the per-context-per-class
-// data structure.
-// Here we map back from the index to the address of the object ref.
-PTR_VOID Context::CalculateAddressForManagedStatic(int slot)
-{
- CONTRACT (PTR_VOID)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_COOPERATIVE;
- PRECONDITION(CheckPointer(this));
- POSTCONDITION(CheckPointer(RETVAL));
- SUPPORTS_DAC;
- }
- CONTRACT_END;
-
- PTR_OBJECTREF pObjRef;
- int bucket = (slot>>16);
- int index = (0x0000ffff&slot);
-
- // Now determine the address of the static field
- PTRARRAYREF bucketRef = NULL;
-
- bucketRef = ((CONTEXTBASEREF)GetExposedObjectRaw())->GetContextStaticsHolder();
-
- // walk the chain to our bucket
- while (bucket--)
- bucketRef = (PTRARRAYREF) bucketRef->GetAt(0);
-
- // Index 0 is used to point to the next bucket!
- _ASSERTE(index > 0);
- pObjRef = PTR_OBJECTREF(bucketRef->GetDataPtr())+index;
-
- RETURN (PTR_VOID(pObjRef));
-}
-
-#endif // FEATURE_REMOTING
#ifdef DACCESS_COMPILE