summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAditya Mandaleeka <adityamandaleeka@users.noreply.github.com>2017-04-01 12:25:08 -0700
committerGitHub <noreply@github.com>2017-04-01 12:25:08 -0700
commit036ff00ad33e3bdd8f0eef7513af331eb841d5b9 (patch)
treea0fad66ce5474a1090433d673ccd67316a7200bb /src
parentb1928070df5ab896e9b3f635f577b9be7e848385 (diff)
parent958279de27e7f3c30ad53e35277653d1ec0f1e6e (diff)
downloadcoreclr-036ff00ad33e3bdd8f0eef7513af331eb841d5b9.tar.gz
coreclr-036ff00ad33e3bdd8f0eef7513af331eb841d5b9.tar.bz2
coreclr-036ff00ad33e3bdd8f0eef7513af331eb841d5b9.zip
Merge pull request #10584 from adityamandaleeka/handle_table_local_gc_init
Change how the VM calls ObjectFromHandle.
Diffstat (limited to 'src')
-rw-r--r--src/debug/daccess/dacdbiimpl.cpp4
-rw-r--r--src/debug/daccess/request.cpp4
-rw-r--r--src/gc/gc.cpp6
-rw-r--r--src/gc/gchandletable.cpp10
-rw-r--r--src/gc/gchandletableimpl.h4
-rw-r--r--src/gc/gcinterface.h6
-rw-r--r--src/gc/handletable.h5
-rw-r--r--src/gc/objecthandle.h3
-rw-r--r--src/gc/sample/GCSample.cpp10
-rw-r--r--src/vm/exinfo.h2
-rw-r--r--src/vm/gcheaputilities.cpp36
-rw-r--r--src/vm/gcheaputilities.h17
12 files changed, 90 insertions, 17 deletions
diff --git a/src/debug/daccess/dacdbiimpl.cpp b/src/debug/daccess/dacdbiimpl.cpp
index 74ba14f2eb..605d5c7cee 100644
--- a/src/debug/daccess/dacdbiimpl.cpp
+++ b/src/debug/daccess/dacdbiimpl.cpp
@@ -5718,9 +5718,9 @@ BOOL DacDbiInterfaceImpl::IsVmObjectHandleValid(VMPTR_OBJECTHANDLE vmHandle)
// SEH exceptions will be caught
EX_TRY
{
- OBJECTREF objRef = ObjectFromHandle((OBJECTHANDLE)vmHandle.GetDacPtr());
+ OBJECTREF objRef = HndFetchHandle((OBJECTHANDLE)vmHandle.GetDacPtr());
- // NULL is certinally valid...
+ // NULL is certainly valid...
if (objRef != NULL)
{
if (objRef->ValidateObjectWithPossibleAV())
diff --git a/src/debug/daccess/request.cpp b/src/debug/daccess/request.cpp
index c30501f374..c52b6cd3c1 100644
--- a/src/debug/daccess/request.cpp
+++ b/src/debug/daccess/request.cpp
@@ -3890,7 +3890,7 @@ HRESULT ClrDataAccess::GetClrWatsonBucketsWorker(Thread * pThread, GenericModeBl
if (ohThrowable != NULL)
{
// Get the object from handle and check if the throwable is preallocated or not
- OBJECTREF oThrowable = ObjectFromHandle(ohThrowable);
+ OBJECTREF oThrowable = ::HndFetchHandle(ohThrowable);
if (oThrowable != NULL)
{
// Does the throwable have buckets?
@@ -4184,7 +4184,7 @@ HRESULT ClrDataAccess::GetCCWData(CLRDATA_ADDRESS ccw, struct DacpCCWData *ccwDa
ccwData->isAggregated = pCCW->GetSimpleWrapper()->IsAggregated();
if (pCCW->GetObjectHandle() != NULL)
- ccwData->managedObject = PTR_CDADDR(ObjectFromHandle(pCCW->GetObjectHandle()));
+ ccwData->managedObject = PTR_CDADDR(::HndFetchHandle(pCCW->GetObjectHandle()));
// count the number of COM vtables
ccwData->interfaceCount = 0;
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index 65c6742878..515069b7c2 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -34207,11 +34207,11 @@ bool GCHeap::StressHeap(gc_alloc_context * context)
StringObject* str;
// If the current string is used up
- if (ObjectFromHandle(m_StressObjs[m_CurStressObj]) == 0)
+ if (HndFetchHandle(m_StressObjs[m_CurStressObj]) == 0)
{
// Populate handles with strings
int i = m_CurStressObj;
- while(ObjectFromHandle(m_StressObjs[i]) == 0)
+ while(HndFetchHandle(m_StressObjs[i]) == 0)
{
_ASSERTE(m_StressObjs[i] != 0);
unsigned strLen = (LARGE_OBJECT_SIZE - 32) / sizeof(WCHAR);
@@ -34243,7 +34243,7 @@ bool GCHeap::StressHeap(gc_alloc_context * context)
}
// Get the current string
- str = (StringObject*) OBJECTREFToObject(ObjectFromHandle(m_StressObjs[m_CurStressObj]));
+ str = (StringObject*) OBJECTREFToObject(HndFetchHandle(m_StressObjs[m_CurStressObj]));
if (str)
{
// Chop off the end of the string and form a new object out of it.
diff --git a/src/gc/gchandletable.cpp b/src/gc/gchandletable.cpp
index a4c3352b86..f468bd300f 100644
--- a/src/gc/gchandletable.cpp
+++ b/src/gc/gchandletable.cpp
@@ -22,3 +22,13 @@ void GCHandleTable::Shutdown()
{
Ref_Shutdown();
}
+
+void* GCHandleTable::GetHandleTableContext(void* handleTable)
+{
+ return (void*)((uintptr_t)::HndGetHandleTableADIndex((HHANDLETABLE)handleTable).m_dwIndex);
+}
+
+void* GCHandleTable::GetHandleTableForHandle(OBJECTHANDLE handle)
+{
+ return (void*)::HndGetHandleTable(handle);
+}
diff --git a/src/gc/gchandletableimpl.h b/src/gc/gchandletableimpl.h
index 233e326a64..11fa163df7 100644
--- a/src/gc/gchandletableimpl.h
+++ b/src/gc/gchandletableimpl.h
@@ -13,6 +13,10 @@ public:
virtual bool Initialize();
virtual void Shutdown();
+
+ virtual void* GetHandleTableContext(void* handleTable);
+
+ virtual void* GetHandleTableForHandle(OBJECTHANDLE handle);
};
#endif // GCHANDLETABLE_H_
diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h
index 77425b1cc3..b5a9e0e8f9 100644
--- a/src/gc/gcinterface.h
+++ b/src/gc/gcinterface.h
@@ -149,7 +149,7 @@ struct segment_info
void * pvMem; // base of the allocation, not the first object (must add ibFirstObject)
size_t ibFirstObject; // offset to the base of the first object in the segment
size_t ibAllocated; // limit of allocated memory in the segment (>= firstobject)
- size_t ibCommit; // limit of committed memory in the segment (>= alllocated)
+ size_t ibCommit; // limit of committed memory in the segment (>= allocated)
size_t ibReserved; // limit of reserved memory in the segment (>= commit)
};
@@ -391,6 +391,10 @@ public:
virtual bool Initialize() = 0;
virtual void Shutdown() = 0;
+
+ virtual void* GetHandleTableContext(void* handleTable) = 0;
+
+ virtual void* GetHandleTableForHandle(OBJECTHANDLE handle) = 0;
};
// IGCHeap is the interface that the VM will use when interacting with the GC.
diff --git a/src/gc/handletable.h b/src/gc/handletable.h
index 2e847659f3..5b0299fe02 100644
--- a/src/gc/handletable.h
+++ b/src/gc/handletable.h
@@ -177,8 +177,11 @@ BOOL HndFirstAssignHandle(OBJECTHANDLE handle, OBJECTREF objref);
/*
* inline handle dereferencing
+ *
+ * NOTE: Changes to this implementation should be kept in sync with ObjectFromHandle
+ * on the VM side.
+ *
*/
-
FORCEINLINE OBJECTREF HndFetchHandle(OBJECTHANDLE handle)
{
WRAPPER_NO_CONTRACT;
diff --git a/src/gc/objecthandle.h b/src/gc/objecthandle.h
index b86572b276..386c5d4512 100644
--- a/src/gc/objecthandle.h
+++ b/src/gc/objecthandle.h
@@ -27,7 +27,6 @@
* non-NULL. In other words, if this handle is being initialized for the first
* time.
*/
-#define ObjectFromHandle(handle) HndFetchHandle(handle)
#define StoreObjectInHandle(handle, object) HndAssignHandle(handle, object)
#define InterlockedCompareExchangeObjectInHandle(handle, object, oldObj) HndInterlockedCompareExchangeHandle(handle, object, oldObj)
#define StoreFirstObjectInHandle(handle, object) HndFirstAssignHandle(handle, object)
@@ -119,7 +118,7 @@ inline OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle) {
WRAPPER_NO_CONTRACT;
// Create a new STRONG handle in the same table as an existing handle.
- return HndCreateHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, ObjectFromHandle(handle));
+ return HndCreateHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, HndFetchHandle(handle));
}
diff --git a/src/gc/sample/GCSample.cpp b/src/gc/sample/GCSample.cpp
index 5d5371c76e..45915c0d04 100644
--- a/src/gc/sample/GCSample.cpp
+++ b/src/gc/sample/GCSample.cpp
@@ -207,24 +207,24 @@ int __cdecl main(int argc, char* argv[])
for (int i = 0; i < 1000000; i++)
{
- Object * pBefore = ((My *)ObjectFromHandle(oh))->m_pOther1;
+ Object * pBefore = ((My *)HndFetchHandle(oh))->m_pOther1;
// Allocate more instances of the same object
Object * p = AllocateObject(pMyMethodTable);
if (p == NULL)
return -1;
- Object * pAfter = ((My *)ObjectFromHandle(oh))->m_pOther1;
+ Object * pAfter = ((My *)HndFetchHandle(oh))->m_pOther1;
// Uncomment this assert to see how GC triggered inside AllocateObject moved objects around
// assert(pBefore == pAfter);
// Store the newly allocated object into a field using WriteBarrier
- WriteBarrier(&(((My *)ObjectFromHandle(oh))->m_pOther1), p);
+ WriteBarrier(&(((My *)HndFetchHandle(oh))->m_pOther1), p);
}
// Create weak handle that points to our object
- OBJECTHANDLE ohWeak = CreateGlobalWeakHandle(ObjectFromHandle(oh));
+ OBJECTHANDLE ohWeak = CreateGlobalWeakHandle(HndFetchHandle(oh));
if (ohWeak == NULL)
return -1;
@@ -235,7 +235,7 @@ int __cdecl main(int argc, char* argv[])
pGCHeap->GarbageCollect();
// Verify that the weak handle got cleared by the GC
- assert(ObjectFromHandle(ohWeak) == NULL);
+ assert(HndFetchHandle(ohWeak) == NULL);
printf("Done\n");
diff --git a/src/vm/exinfo.h b/src/vm/exinfo.h
index 6b34e71116..4a6c3e5dcc 100644
--- a/src/vm/exinfo.h
+++ b/src/vm/exinfo.h
@@ -134,7 +134,7 @@ public:
return m_pPrevNestedInfo;
}
- // Returns the throwble associated with the tracker
+ // Returns the throwable associated with the tracker
inline OBJECTREF GetThrowable()
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/vm/gcheaputilities.cpp b/src/vm/gcheaputilities.cpp
index aa90341159..730728927a 100644
--- a/src/vm/gcheaputilities.cpp
+++ b/src/vm/gcheaputilities.cpp
@@ -4,6 +4,8 @@
#include "common.h"
#include "gcheaputilities.h"
+#include "appdomain.hpp"
+
// These globals are variables used within the GC and maintained
// by the EE for use in write barriers. It is the responsibility
@@ -36,3 +38,37 @@ bool g_sw_ww_enabled_for_gc_heap = false;
gc_alloc_context g_global_alloc_context = {};
+// Debug-only validation for handle.
+void ValidateHandleAndAppDomain(OBJECTHANDLE handle)
+{
+#ifdef _DEBUG_IMPL
+ OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
+ VALIDATEOBJECTREF(objRef);
+
+ IGCHandleTable *pHandleTable = GCHeapUtilities::GetGCHandleTable();
+
+ void* handleTable = pHandleTable->GetHandleTableForHandle(handle);
+ DWORD context = (DWORD)pHandleTable->GetHandleTableContext(handleTable);
+
+ ADIndex appDomainIndex = ADIndex(context);
+ AppDomain *domain = SystemDomain::GetAppDomainAtIndex(appDomainIndex);
+
+ // Access to a handle in an unloaded domain is not allowed
+ 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/gcheaputilities.h b/src/vm/gcheaputilities.h
index 1e920127fe..064165bc11 100644
--- a/src/vm/gcheaputilities.h
+++ b/src/vm/gcheaputilities.h
@@ -209,5 +209,22 @@ private:
GCHeapUtilities() = delete;
};
+// Handle-related utilities.
+
+void ValidateHandleAndAppDomain(OBJECTHANDLE handle);
+
+// Given a handle, returns an OBJECTREF for the object it refers to.
+inline OBJECTREF ObjectFromHandle(OBJECTHANDLE handle)
+{
+ _ASSERTE(handle);
+
+#ifdef _DEBUG_IMPL
+ ValidateHandleAndAppDomain(handle);
+#endif // _DEBUG_IMPL
+
+ // Wrap the raw OBJECTREF and return it
+ return UNCHECKED_OBJECTREF_TO_OBJECTREF(*PTR_UNCHECKED_OBJECTREF(handle));
+}
+
#endif // _GCHEAPUTILITIES_H_