summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPat Gavlin <pagavlin@microsoft.com>2016-03-03 11:51:59 -0800
committerPat Gavlin <pagavlin@microsoft.com>2016-03-03 11:51:59 -0800
commite2df0fdbfaa688de075f020a1bf59e30fffe9fb9 (patch)
tree5611fcf0839efa44e52bff4d18a58eed852329b4
parenta70b732323b8be45a80fcd1488d60c7baa9ab0a3 (diff)
downloadcoreclr-e2df0fdbfaa688de075f020a1bf59e30fffe9fb9.tar.gz
coreclr-e2df0fdbfaa688de075f020a1bf59e30fffe9fb9.tar.bz2
coreclr-e2df0fdbfaa688de075f020a1bf59e30fffe9fb9.zip
Refactor Utilcode's IAllocators.
- `DefaultAllocator` has been replaced with `HostAllocator` in RyuJIT, which uses the JIT hosting interface to allocate and free memory. - The definition of `DefaultAllocator` has been moved into its own file, as it remains in use by the interpreter and the binder. - `ProcessHeapAllocator` has been moved into JIT32, as that was its only remaining user. - `AllowZeroAllocator`'s static field has been changed to an instance field to avoid the need to define storage for the static field in Utilcode. [tfs-changeset: 1581242]
-rw-r--r--src/inc/iallocator.h104
-rw-r--r--src/inc/simplerhash.inl2
-rw-r--r--src/jit/CMakeLists.txt1
-rw-r--r--src/jit/compiler.cpp23
-rw-r--r--src/jit/ee_il_dll.cpp2
-rw-r--r--src/jit/ee_il_dll.hpp2
-rw-r--r--src/jit/emit.cpp7
-rw-r--r--src/jit/hostallocator.cpp40
-rw-r--r--src/jit/hostallocator.h20
-rw-r--r--src/jit/jit.settings.targets1
-rw-r--r--src/utilcode/iallocator.cpp6
-rw-r--r--src/vm/interpreter.cpp5
12 files changed, 93 insertions, 120 deletions
diff --git a/src/inc/iallocator.h b/src/inc/iallocator.h
index fea024171e..b4c1b71120 100644
--- a/src/inc/iallocator.h
+++ b/src/inc/iallocator.h
@@ -30,55 +30,12 @@ class IAllocator
virtual void Free(void* p) = 0;
};
-// The "DefaultAllocator" class may be used by classes that wish to
-// provide the flexibility of using an "IAllocator" may avoid writing
-// conditionals at allocation sites about whether a non-default
-// "IAllocator" has been provided: if none is, they can simply set the
-// allocator to DefaultAllocator::Singleton().
-
-class DefaultAllocator: public IAllocator
-{
- static DefaultAllocator s_singleton;
-
- public:
- void* Alloc(size_t sz)
- {
- return ::operator new(sz);
- }
-
- void* ArrayAlloc(size_t elemSize, size_t numElems)
- {
- ClrSafeInt<size_t> safeElemSize(elemSize);
- ClrSafeInt<size_t> safeNumElems(numElems);
- ClrSafeInt<size_t> sz = safeElemSize * safeNumElems;
- if (sz.IsOverflow())
- {
- return NULL;
- }
- else
- {
- return ::operator new(sz.Value());
- }
- }
-
- virtual void Free(void * p)
- {
- ::operator delete(p);
- }
-
- static DefaultAllocator* Singleton()
- {
- return &s_singleton;
- }
-};
-
// This class wraps an allocator that does not allow zero-length allocations,
-// producing one that does (every zero-length allocation produces a pointer to the same
+// producing one that does (every zero-length allocation produces a pointer to the same
// statically-allocated memory, and freeing that pointer is a no-op).
class AllowZeroAllocator: public IAllocator
{
- static int s_zeroLenAllocTarg;
-
+ int m_zeroLenAllocTarg;
IAllocator* m_alloc;
public:
@@ -87,8 +44,8 @@ public:
void* Alloc(size_t sz)
{
if (sz == 0)
- {
- return (void*)(&s_zeroLenAllocTarg);
+ {
+ return (void*)(&m_zeroLenAllocTarg);
}
else
{
@@ -99,8 +56,8 @@ public:
void* ArrayAlloc(size_t elemSize, size_t numElems)
{
if (elemSize == 0 || numElems == 0)
- {
- return (void*)(&s_zeroLenAllocTarg);
+ {
+ return (void*)(&m_zeroLenAllocTarg);
}
else
{
@@ -110,58 +67,11 @@ public:
virtual void Free(void * p)
{
- if (p != (void*)(&s_zeroLenAllocTarg))
+ if (p != (void*)(&m_zeroLenAllocTarg))
{
m_alloc->Free(p);
}
}
};
-
-// ProcessHeapAllocator: This class implements an IAllocator that allocates and frees memory
-// from the process heap. This is similar to DefaultAllocator, but it can be used by the JIT
-// which doesn't allow the use of operator new/delete.
-
-class ProcessHeapAllocator: public IAllocator
-{
- static ProcessHeapAllocator s_singleton;
-
-public:
-
- virtual void* Alloc(size_t sz)
- {
- return ClrAllocInProcessHeap(0, S_SIZE_T(sz));
- }
-
- virtual void* ArrayAlloc(size_t elemSize, size_t numElems)
- {
- ClrSafeInt<size_t> safeElemSize(elemSize);
- ClrSafeInt<size_t> safeNumElems(numElems);
- ClrSafeInt<size_t> sz = safeElemSize * safeNumElems;
- if (sz.IsOverflow())
- {
- return nullptr;
- }
- else
- {
- return ClrAllocInProcessHeap(0, S_SIZE_T(sz));
- }
- }
-
- virtual void Free(void* p)
- {
- if (p != nullptr)
- {
- (void)ClrFreeInProcessHeap(0, p);
- }
- }
-
- static ProcessHeapAllocator* Singleton()
- {
- return &s_singleton;
- }
-};
-
#endif // _IALLOCATOR_DEFINED_
-
-
diff --git a/src/inc/simplerhash.inl b/src/inc/simplerhash.inl
index 1a7d004b26..091f047311 100644
--- a/src/inc/simplerhash.inl
+++ b/src/inc/simplerhash.inl
@@ -51,7 +51,7 @@ SimplerHashTable<Key,KeyFuncs,Value,Behavior>::SimplerHashTable(IAllocator* allo
{
LIMITED_METHOD_CONTRACT;
- if (m_alloc == NULL) m_alloc = DefaultAllocator::Singleton();
+ assert(m_alloc != nullptr);
#ifndef __GNUC__ // these crash GCC
static_assert_no_msg(Behavior::s_growth_factor_numerator > Behavior::s_growth_factor_denominator);
diff --git a/src/jit/CMakeLists.txt b/src/jit/CMakeLists.txt
index b18b8cf3be..b492cf7a9c 100644
--- a/src/jit/CMakeLists.txt
+++ b/src/jit/CMakeLists.txt
@@ -32,6 +32,7 @@ set( JIT_SOURCES
gentree.cpp
gschecks.cpp
hashbv.cpp
+ hostallocator.cpp
importer.cpp
inline.cpp
inlinepolicy.cpp
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp
index 264286679a..ca9726f04f 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -14,6 +14,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#ifdef _MSC_VER
#pragma hdrstop
#endif // _MSC_VER
+#include "hostallocator.h"
#include "emit.h"
#include "ssabuilder.h"
#include "valuenum.h"
@@ -246,10 +247,10 @@ NodeSizeStats genNodeSizeStats;
NodeSizeStats genNodeSizeStatsPerFunc;
unsigned genTreeNcntHistBuckets[] = { 10, 20, 30, 40, 50, 100, 200, 300, 400, 500, 1000, 5000, 10000, 0 };
-histo genTreeNcntHist(DefaultAllocator::Singleton(), genTreeNcntHistBuckets);
+histo genTreeNcntHist(HostAllocator::getHostAllocator(), genTreeNcntHistBuckets);
unsigned genTreeNsizHistBuckets[] = { 1000, 5000, 10000, 50000, 100000, 500000, 1000000, 0 };
-histo genTreeNsizHist(DefaultAllocator::Singleton(), genTreeNsizHistBuckets);
+histo genTreeNsizHist(HostAllocator::getHostAllocator(), genTreeNsizHistBuckets);
#endif // MEASURE_NODE_SIZE
/*****************************************************************************
@@ -300,16 +301,16 @@ unsigned argTotalGTF_ASGinArgs;
unsigned argMaxTempsPerMethod;
unsigned argCntBuckets[] = { 0, 1, 2, 3, 4, 5, 6, 10, 0 };
-histo argCntTable(DefaultAllocator::Singleton(), argCntBuckets);
+histo argCntTable(HostAllocator::getHostAllocator(), argCntBuckets);
unsigned argDWordCntBuckets[] = { 0, 1, 2, 3, 4, 5, 6, 10, 0 };
-histo argDWordCntTable(DefaultAllocator::Singleton(), argDWordCntBuckets);
+histo argDWordCntTable(HostAllocator::getHostAllocator(), argDWordCntBuckets);
unsigned argDWordLngCntBuckets[] = { 0, 1, 2, 3, 4, 5, 6, 10, 0 };
-histo argDWordLngCntTable(DefaultAllocator::Singleton(), argDWordLngCntBuckets);
+histo argDWordLngCntTable(HostAllocator::getHostAllocator(), argDWordLngCntBuckets);
unsigned argTempsCntBuckets[] = { 0, 1, 2, 3, 4, 5, 6, 10, 0 };
-histo argTempsCntTable(DefaultAllocator::Singleton(), argTempsCntBuckets);
+histo argTempsCntTable(HostAllocator::getHostAllocator(), argTempsCntBuckets);
#endif // CALL_ARG_STATS
@@ -336,12 +337,12 @@ histo argTempsCntTable(DefaultAllocator::Singleton(), argTempsCntBuckets);
// --------------------------------------------------
unsigned bbCntBuckets[] = { 1, 2, 3, 5, 10, 20, 50, 100, 1000, 10000, 0 };
-histo bbCntTable(DefaultAllocator::Singleton(), bbCntBuckets);
+histo bbCntTable(HostAllocator::getHostAllocator(), bbCntBuckets);
/* Histogram for the IL opcode size of methods with a single basic block */
unsigned bbSizeBuckets[] = { 1, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 0 };
-histo bbOneBBSizeTable(DefaultAllocator::Singleton(), bbSizeBuckets);
+histo bbOneBBSizeTable(HostAllocator::getHostAllocator(), bbSizeBuckets);
#endif // COUNT_BASIC_BLOCKS
@@ -373,12 +374,12 @@ bool loopOverflowThisMethod; // True if we exceeded the max # of loop
/* Histogram for number of loops in a method */
unsigned loopCountBuckets[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0 };
-histo loopCountTable(DefaultAllocator::Singleton(), loopCountBuckets);
+histo loopCountTable(HostAllocator::getHostAllocator(), loopCountBuckets);
/* Histogram for number of loop exits */
unsigned loopExitCountBuckets[] = { 0, 1, 2, 3, 4, 5, 6, 0 };
-histo loopExitCountTable(DefaultAllocator::Singleton(), loopExitCountBuckets);
+histo loopExitCountTable(HostAllocator::getHostAllocator(), loopExitCountBuckets);
#endif // COUNT_LOOPS
@@ -2113,7 +2114,7 @@ void Compiler::compInitOptions(CORJIT_FLAGS* jitFlags)
{
// NOTE: The Assembly name list is allocated in the process heap, not in the no-release heap, which is reclaimed
// for every compilation. This is ok because we only allocate once, due to the static.
- s_pAltJitExcludeAssembliesList = new (ProcessHeapAllocator::Singleton()) AssemblyNamesList2(wszAltJitExcludeAssemblyList, ProcessHeapAllocator::Singleton());
+ s_pAltJitExcludeAssembliesList = new (HostAllocator::getHostAllocator()) AssemblyNamesList2(wszAltJitExcludeAssemblyList, HostAllocator::getHostAllocator());
}
}
diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp
index dc069fe0e6..da0ae901fe 100644
--- a/src/jit/ee_il_dll.cpp
+++ b/src/jit/ee_il_dll.cpp
@@ -22,7 +22,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
/*****************************************************************************/
-static ICorJitHost* g_jitHost = nullptr;
+ICorJitHost* g_jitHost = nullptr;
static CILJit* ILJitter = 0; // The one and only JITTER I return
#ifndef FEATURE_MERGE_JIT_AND_ENGINE
HINSTANCE g_hInst = NULL;
diff --git a/src/jit/ee_il_dll.hpp b/src/jit/ee_il_dll.hpp
index c61deb57a1..b1e0327d6b 100644
--- a/src/jit/ee_il_dll.hpp
+++ b/src/jit/ee_il_dll.hpp
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+extern ICorJitHost* g_jitHost;
+
class CILJit: public ICorJitCompiler
{
CorJitResult __stdcall compileMethod (
diff --git a/src/jit/emit.cpp b/src/jit/emit.cpp
index 493d13cde0..e5b6842b14 100644
--- a/src/jit/emit.cpp
+++ b/src/jit/emit.cpp
@@ -16,6 +16,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#pragma hdrstop
#endif
+#include "hostallocator.h"
#include "instr.h"
#include "emit.h"
#include "codegen.h"
@@ -264,13 +265,13 @@ static unsigned totActualSize;
unsigned emitter::emitIFcounts[emitter::IF_COUNT];
static unsigned emitSizeBuckets[] = { 100, 1024*1, 1024*2, 1024*3, 1024*4, 1024*5, 1024*10, 0 };
-static histo emitSizeTable(DefaultAllocator::Singleton(), emitSizeBuckets);
+static histo emitSizeTable(HostAllocator::getHostAllocator(), emitSizeBuckets);
static unsigned GCrefsBuckets[] = { 0, 1, 2, 5, 10, 20, 50, 128, 256, 512, 1024, 0 };
-static histo GCrefsTable(DefaultAllocator::Singleton(), GCrefsBuckets);
+static histo GCrefsTable(HostAllocator::getHostAllocator(), GCrefsBuckets);
static unsigned stkDepthBuckets[] = { 0, 1, 2, 5, 10, 16, 32, 128, 1024, 0 };
-static histo stkDepthTable(DefaultAllocator::Singleton(), stkDepthBuckets);
+static histo stkDepthTable(HostAllocator::getHostAllocator(), stkDepthBuckets);
size_t emitter::emitSizeMethod;
diff --git a/src/jit/hostallocator.cpp b/src/jit/hostallocator.cpp
new file mode 100644
index 0000000000..b737424ee8
--- /dev/null
+++ b/src/jit/hostallocator.cpp
@@ -0,0 +1,40 @@
+// 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.
+
+#include "jitpch.h"
+#include "hostallocator.h"
+
+HostAllocator HostAllocator::s_hostAllocator;
+
+void* HostAllocator::Alloc(size_t size)
+{
+ assert(g_jitHost != nullptr);
+ return g_jitHost->allocateMemory(size, false);
+}
+
+void* HostAllocator::ArrayAlloc(size_t elemSize, size_t numElems)
+{
+ assert(g_jitHost != nullptr);
+
+ ClrSafeInt<size_t> safeElemSize(elemSize);
+ ClrSafeInt<size_t> safeNumElems(numElems);
+ ClrSafeInt<size_t> size = safeElemSize * safeNumElems;
+ if (size.IsOverflow())
+ {
+ return nullptr;
+ }
+
+ return g_jitHost->allocateMemory(size.Value(), false);
+}
+
+void HostAllocator::Free(void* p)
+{
+ assert(g_jitHost != nullptr);
+ g_jitHost->freeMemory(p, false);
+}
+
+HostAllocator* HostAllocator::getHostAllocator()
+{
+ return &s_hostAllocator;
+}
diff --git a/src/jit/hostallocator.h b/src/jit/hostallocator.h
new file mode 100644
index 0000000000..c51eccc75e
--- /dev/null
+++ b/src/jit/hostallocator.h
@@ -0,0 +1,20 @@
+// 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.
+
+class HostAllocator : public IAllocator
+{
+private:
+ static HostAllocator s_hostAllocator;
+
+ HostAllocator() {}
+
+public:
+ void* Alloc(size_t size) override;
+
+ void* ArrayAlloc(size_t elemSize, size_t numElems) override;
+
+ void Free(void* p) override;
+
+ static HostAllocator* getHostAllocator();
+};
diff --git a/src/jit/jit.settings.targets b/src/jit/jit.settings.targets
index dfbe8f85f9..b95852f63c 100644
--- a/src/jit/jit.settings.targets
+++ b/src/jit/jit.settings.targets
@@ -82,6 +82,7 @@
<CppCompile Include="..\LoopCloning.cpp" />
<CppCompile Include="..\inline.cpp" />
<CppCompile Include="..\inlinepolicy.cpp" />
+ <CppCompile Include="..\hostallocator.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='True'" Include="..\CodeGenLegacy.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\Lower.cpp" />
<CppCompile Condition="'$(ClDefines.Contains(`LEGACY_BACKEND`))'=='False'" Include="..\LSRA.cpp" />
diff --git a/src/utilcode/iallocator.cpp b/src/utilcode/iallocator.cpp
index d6dabc7f2e..8c5fc838e5 100644
--- a/src/utilcode/iallocator.cpp
+++ b/src/utilcode/iallocator.cpp
@@ -4,11 +4,7 @@
#include "stdafx.h" // Precompiled header key.
#include "iallocator.h"
+#include "defaultallocator.h"
// static
DefaultAllocator DefaultAllocator::s_singleton;
-
-// static
-ProcessHeapAllocator ProcessHeapAllocator::s_singleton;
-
-int AllowZeroAllocator::s_zeroLenAllocTarg;
diff --git a/src/vm/interpreter.cpp b/src/vm/interpreter.cpp
index a846e424df..bdfa9622f9 100644
--- a/src/vm/interpreter.cpp
+++ b/src/vm/interpreter.cpp
@@ -23,6 +23,7 @@
#include "runtimehandles.h"
#include "vars.hpp"
#include "cycletimer.h"
+#include "defaultallocator.h"
#ifdef FEATURE_REMOTING
#include "remoting.h"
#endif
@@ -10837,7 +10838,7 @@ Interpreter::AddrToMDMap* Interpreter::GetAddrToMdMap()
if (s_addrToMDMap == NULL)
{
- s_addrToMDMap = new AddrToMDMap(/* use default allocator */ NULL);
+ s_addrToMDMap = new AddrToMDMap(DefaultAllocator::Singleton());
}
return s_addrToMDMap;
}
@@ -10899,7 +10900,7 @@ Interpreter::MethodHandleToInterpMethInfoPtrMap* Interpreter::GetMethodHandleToI
if (s_methodHandleToInterpMethInfoPtrMap == NULL)
{
- s_methodHandleToInterpMethInfoPtrMap = new MethodHandleToInterpMethInfoPtrMap(/* use default allocator */ NULL);
+ s_methodHandleToInterpMethInfoPtrMap = new MethodHandleToInterpMethInfoPtrMap(DefaultAllocator::Singleton());
}
return s_methodHandleToInterpMethInfoPtrMap;
}