Skip to content

Commit 212c3bb

Browse files
committed
Define a mempool new operator for InterpCompiler like the one in the JIT and use it to allocate the GcInfoEncoder
Throw std::bad_alloc from Interp_NOMEM instead of trapping
1 parent 54b74f1 commit 212c3bb

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

src/coreclr/interpreter/compiler.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "interpreter.h"
55

66
#include <inttypes.h>
7+
#include <new> // for std::bad_alloc
78

89
static const StackType g_stackTypeFromInterpType[] =
910
{
@@ -37,12 +38,7 @@ static const char *g_stackTypeString[] = { "I4", "I8", "R4", "R8", "O ", "VT", "
3738
/*****************************************************************************/
3839
void DECLSPEC_NORETURN Interp_NOMEM()
3940
{
40-
// Ensure we don't return and that the compiler knows we won't
41-
#ifdef _MSC_VER
42-
__debugbreak();
43-
#else
44-
__builtin_trap();
45-
#endif
41+
throw std::bad_alloc();
4642
}
4743

4844
// GCInfoEncoder needs an IAllocator implementation. This is a simple one that forwards to the Compiler.
@@ -859,8 +855,8 @@ void InterpCompiler::EmitCode()
859855
void InterpCompiler::BuildGCInfo(InterpMethod *pInterpMethod)
860856
{
861857
#ifdef FEATURE_INTERPRETER
862-
InterpIAllocator* pAllocator = new InterpIAllocator(this);
863-
InterpreterGcInfoEncoder* gcInfoEncoder = new InterpreterGcInfoEncoder(m_compHnd, m_methodInfo, pAllocator, Interp_NOMEM);
858+
InterpIAllocator* pAllocator = new (this) InterpIAllocator(this);
859+
InterpreterGcInfoEncoder* gcInfoEncoder = new (this) InterpreterGcInfoEncoder(m_compHnd, m_methodInfo, pAllocator, Interp_NOMEM);
864860
assert(gcInfoEncoder);
865861

866862
gcInfoEncoder->SetCodeLength(m_methodCodeSize);
@@ -876,11 +872,6 @@ void InterpCompiler::BuildGCInfo(InterpMethod *pInterpMethod)
876872
// GC Encoder automatically puts the GC info in the right spot using ICorJitInfo::allocGCInfo(size_t)
877873
// let's save the values anyway for debugging purposes
878874
gcInfoEncoder->Emit();
879-
880-
// Interpreter-FIXME: Why doesn't the JIT code do this? Is it because the placement new it uses automatically frees them
881-
// at the end of JIT compilation?
882-
delete gcInfoEncoder;
883-
delete pAllocator;
884875
#endif
885876
}
886877

src/coreclr/interpreter/compiler.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,10 +295,12 @@ class InterpCompiler
295295
CORINFO_CLASS_HANDLE ResolveClassToken(uint32_t token);
296296

297297
void* AllocMethodData(size_t numBytes);
298+
public:
298299
// FIXME Mempool allocation currently leaks. We need to add an allocator and then
299300
// free all memory when method is finished compilling.
300301
void* AllocMemPool(size_t numBytes);
301302
void* AllocMemPool0(size_t numBytes);
303+
private:
302304
void* AllocTemporary(size_t numBytes);
303305
void* AllocTemporary0(size_t numBytes);
304306
void* ReallocTemporary(void* ptr, size_t numBytes);
@@ -436,4 +438,20 @@ class InterpCompiler
436438
int32_t* GetCode(int32_t *pCodeSize);
437439
};
438440

441+
/*****************************************************************************
442+
* operator new
443+
*
444+
* Uses the compiler's AllocMemPool0, which will eventually free automatically at the end of compilation (doesn't yet).
445+
*/
446+
447+
inline void* operator new(size_t sz, InterpCompiler* compiler)
448+
{
449+
return compiler->AllocMemPool0(sz);
450+
}
451+
452+
inline void* operator new[](size_t sz, InterpCompiler* compiler)
453+
{
454+
return compiler->AllocMemPool0(sz);
455+
}
456+
439457
#endif //_COMPILER_H_

0 commit comments

Comments
 (0)