summaryrefslogtreecommitdiff
path: root/src/vm/pendingload.h
diff options
context:
space:
mode:
authorJiyoung Yun <jy910.yun@samsung.com>2016-11-23 19:09:09 +0900
committerJiyoung Yun <jy910.yun@samsung.com>2016-11-23 19:09:09 +0900
commit4b4aad7217d3292650e77eec2cf4c198ea9c3b4b (patch)
tree98110734c91668dfdbb126fcc0e15ddbd93738ca /src/vm/pendingload.h
parentfa45f57ed55137c75ac870356a1b8f76c84b229c (diff)
downloadcoreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.gz
coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.tar.bz2
coreclr-4b4aad7217d3292650e77eec2cf4c198ea9c3b4b.zip
Imported Upstream version 1.1.0upstream/1.1.0
Diffstat (limited to 'src/vm/pendingload.h')
-rw-r--r--src/vm/pendingload.h265
1 files changed, 265 insertions, 0 deletions
diff --git a/src/vm/pendingload.h b/src/vm/pendingload.h
new file mode 100644
index 0000000000..1373215d0a
--- /dev/null
+++ b/src/vm/pendingload.h
@@ -0,0 +1,265 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//
+// pendingload.h
+//
+
+//
+
+#ifndef _H_PENDINGLOAD
+#define _H_PENDINGLOAD
+
+#include "crst.h"
+#include "class.h"
+#include "typekey.h"
+#include "typehash.h"
+#include "vars.hpp"
+#include "shash.h"
+#include "typestring.h"
+
+//
+// A temporary structure used when loading and resolving classes
+//
+class PendingTypeLoadEntry
+{
+ friend class ClassLoader; // workaround really need to beef up the API below
+
+public:
+ PendingTypeLoadEntry(TypeKey typeKey, TypeHandle typeHnd)
+ : m_Crst(
+ CrstPendingTypeLoadEntry,
+ CrstFlags(CRST_HOST_BREAKABLE|CRST_UNSAFE_SAMELEVEL)
+ ),
+ m_typeKey(typeKey)
+
+ {
+ WRAPPER_NO_CONTRACT;
+
+ m_typeHandle = typeHnd;
+ m_dwWaitCount = 1;
+ m_hrResult = S_OK;
+ m_pException = NULL;
+#ifdef _DEBUG
+ if (LoggingOn(LF_CLASSLOADER, LL_INFO10000))
+ {
+ SString name;
+ TypeString::AppendTypeKeyDebug(name, &m_typeKey);
+ LOG((LF_CLASSLOADER, LL_INFO10000, "PHASEDLOAD: Creating loading entry for type %S\n", name.GetUnicode()));
+ }
+#endif
+
+ m_fLockAcquired = TRUE;
+
+ //---------------------------------------------------------------------------
+ // The PendingTypeLoadEntry() lock has a higher level than UnresolvedClassLock.
+ // But whenever we create one, we have to acquire it while holding the UnresolvedClassLock.
+ // This is safe since we're the ones that created the lock and are guaranteed to acquire
+ // it without blocking. But to prevent the crstlevel system from asserting, we
+ // must acquire using a special method.
+ //---------------------------------------------------------------------------
+ m_Crst.Enter(INDEBUG(Crst::CRST_NO_LEVEL_CHECK));
+ }
+
+ ~PendingTypeLoadEntry()
+ {
+ LIMITED_METHOD_CONTRACT;
+
+ if (m_fLockAcquired)
+ m_Crst.Leave();
+
+ if (m_pException && !m_pException->IsPreallocatedException()) {
+ delete m_pException;
+ }
+ }
+
+#ifdef _DEBUG
+ BOOL HasLock()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_Crst.OwnedByCurrentThread();
+ }
+#endif
+
+#ifndef DACCESS_COMPILE
+ VOID DECLSPEC_NORETURN ThrowException()
+ {
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ INJECT_FAULT(COMPlusThrowOM(););
+ }
+ CONTRACTL_END;
+
+ if (m_pException)
+ PAL_CPP_THROW(Exception *, m_pException->Clone());
+
+ _ASSERTE(FAILED(m_hrResult));
+
+ if (m_hrResult == COR_E_TYPELOAD)
+ {
+ TypeKey typeKey = GetTypeKey();
+ ClassLoader::ThrowTypeLoadException(&typeKey,
+ IDS_CLASSLOAD_GENERAL);
+
+ }
+ else
+ EX_THROW(EEMessageException, (m_hrResult));
+ }
+
+ void SetException(Exception *pException)
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ PRECONDITION(HasLock());
+ PRECONDITION(m_pException == NULL);
+ PRECONDITION(m_dwWaitCount > 0);
+ }
+ CONTRACTL_END;
+
+ m_typeHandle = TypeHandle();
+ m_hrResult = COR_E_TYPELOAD;
+
+ // we don't care if this fails
+ // we already know the HRESULT so if we can't store
+ // the details - so be it
+ EX_TRY
+ {
+ FAULT_NOT_FATAL();
+ m_pException = pException->Clone();
+ }
+ EX_CATCH
+ {
+ m_pException=NULL;
+ }
+ EX_END_CATCH(SwallowAllExceptions);
+ }
+
+ void SetResult(TypeHandle typeHnd)
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ PRECONDITION(HasLock());
+ PRECONDITION(m_pException == NULL);
+ PRECONDITION(m_dwWaitCount > 0);
+ }
+ CONTRACTL_END;
+
+ m_typeHandle = typeHnd;
+ }
+
+ void UnblockWaiters()
+ {
+ CONTRACTL
+ {
+ NOTHROW;
+ PRECONDITION(HasLock());
+ PRECONDITION(m_dwWaitCount > 0);
+ }
+ CONTRACTL_END;
+
+ _ASSERTE(m_fLockAcquired);
+ m_Crst.Leave();
+ m_fLockAcquired = FALSE;
+ }
+#endif //DACCESS_COMPILE
+
+ TypeKey GetTypeKey()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_typeKey;
+ }
+
+ void AddRef()
+ {
+ LIMITED_METHOD_CONTRACT;
+ InterlockedIncrement(&m_dwWaitCount);
+ }
+
+ void Release()
+ {
+ LIMITED_METHOD_CONTRACT;
+ if (InterlockedDecrement(&m_dwWaitCount) == 0)
+ delete this;
+ }
+
+ BOOL HasWaiters()
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_dwWaitCount > 1;
+ }
+
+ private:
+ Crst m_Crst;
+
+ public:
+ // Result of loading; this is first created in the CREATE stage of class loading
+ TypeHandle m_typeHandle;
+
+ private:
+ // Type that we're loading
+ TypeKey m_typeKey;
+
+ // Number of threads waiting for this type
+ LONG m_dwWaitCount;
+
+ // Error result, propagated to all threads loading this class
+ HRESULT m_hrResult;
+
+ // Exception object to throw
+ Exception *m_pException;
+
+ // m_Crst was acquired
+ BOOL m_fLockAcquired;
+};
+
+// Hash table used to hold pending type loads
+// @todo : use shash.h when Rotor build problems are fixed and it supports LoaderHeap/Alloc\MemTracker
+class PendingTypeLoadTable
+{
+protected:
+ struct TableEntry
+ {
+ TableEntry* pNext;
+ DWORD dwHashValue;
+ PendingTypeLoadEntry* pData;
+ };
+
+ TableEntry **m_pBuckets; // Pointer to first entry for each bucket
+ DWORD m_dwNumBuckets;
+
+public:
+
+#ifdef _DEBUG
+ DWORD m_dwDebugMemory;
+#endif
+
+ static PendingTypeLoadTable *Create(LoaderHeap *pHeap, DWORD dwNumBuckets, AllocMemTracker *pamTracker);
+
+private:
+ // These functions don't actually exist - declared private to prevent bypassing PendingTypeLoadTable::Create
+ void * operator new(size_t size);
+ void operator delete(void *p);
+
+ PendingTypeLoadTable();
+ ~PendingTypeLoadTable();
+
+public:
+ BOOL InsertValue(PendingTypeLoadEntry* pEntry);
+ BOOL DeleteValue(TypeKey *pKey);
+ PendingTypeLoadEntry* GetValue(TypeKey *pKey);
+ TableEntry* AllocNewEntry();
+ void FreeEntry(TableEntry* pEntry);
+#ifdef _DEBUG
+ void Dump();
+#endif
+
+private:
+ TableEntry* FindItem(TypeKey *pKey);
+};
+
+
+#endif // _H_PENDINGLOAD