Browse Source

Fix memory leaks

cl-refactor
Paweł Bylica 10 years ago
parent
commit
32a4bebb79
  1. 10
      libevmjit/Array.cpp
  2. 4
      libevmjit/Common.h
  3. 23
      libevmjit/Compiler.cpp
  4. 9
      libevmjit/Runtime.cpp
  5. 3
      libevmjit/RuntimeManager.cpp
  6. 5
      libevmjit/RuntimeManager.h
  7. 5
      libevmjit/interface.cpp

10
libevmjit/Array.cpp

@ -278,7 +278,11 @@ namespace
~AllocatedMemoryWatchdog()
{
if (!allocatedMemory.empty())
{
DLOG(mem) << allocatedMemory.size() << " MEM LEAKS!\n";
for (auto&& leak : allocatedMemory)
DLOG(mem) << "\t" << leak << "\n";
}
}
};
@ -289,20 +293,20 @@ extern "C"
{
using namespace dev::eth::jit;
EXPORT void* ext_realloc(void* _data, size_t _size)
EXPORT void* ext_realloc(void* _data, size_t _size) noexcept
{
//std::cerr << "REALLOC: " << _data << " [" << _size << "]" << std::endl;
auto newData = std::realloc(_data, _size);
if (_data != newData)
{
DLOG(mem) << "REALLOC: " << _data << " -> " << newData << " [" << _size << "]\n";
DLOG(mem) << "REALLOC: " << newData << " <- " << _data << " [" << _size << "]\n";
watchdog.allocatedMemory.erase(_data);
watchdog.allocatedMemory.insert(newData);
}
return newData;
}
EXPORT void ext_free(void* _data)
EXPORT void ext_free(void* _data) noexcept
{
std::free(_data);
if (_data)

4
libevmjit/Common.h

@ -4,7 +4,9 @@
#include <cstdint>
#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
#define EXPORT __declspec(dllexport)
#define _ALLOW_KEYWORD_MACROS
#define noexcept throw()
#else
#define EXPORT
#endif

23
libevmjit/Compiler.cpp

@ -132,6 +132,17 @@ std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_itera
auto entryBlock = llvm::BasicBlock::Create(m_builder.getContext(), {}, m_mainFunc);
m_builder.SetInsertPoint(entryBlock);
createBasicBlocks(_begin, _end);
// Init runtime structures.
RuntimeManager runtimeManager(m_builder, _begin, _end);
GasMeter gasMeter(m_builder, runtimeManager);
Memory memory(runtimeManager, gasMeter);
Ext ext(runtimeManager, memory);
Stack stack(m_builder, runtimeManager);
runtimeManager.setStack(stack); // Runtime Manager will free stack memory
Arith256 arith(m_builder);
auto jmpBufWords = m_builder.CreateAlloca(Type::BytePtr, m_builder.getInt64(3), "jmpBuf.words");
auto frameaddress = llvm::Intrinsic::getDeclaration(module.get(), llvm::Intrinsic::frameaddress);
auto fp = m_builder.CreateCall(frameaddress, m_builder.getInt32(0), "fp");
@ -144,17 +155,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_itera
auto jmpBuf = m_builder.CreateBitCast(jmpBufWords, Type::BytePtr, "jmpBuf");
auto r = m_builder.CreateCall(setjmp, jmpBuf);
auto normalFlow = m_builder.CreateICmpEQ(r, m_builder.getInt32(0));
createBasicBlocks(_begin, _end);
// Init runtime structures.
RuntimeManager runtimeManager(m_builder, jmpBuf, _begin, _end);
GasMeter gasMeter(m_builder, runtimeManager);
Memory memory(runtimeManager, gasMeter);
Ext ext(runtimeManager, memory);
Stack stack(m_builder, runtimeManager);
runtimeManager.setStack(stack); // Runtime Manager will free stack memory
Arith256 arith(m_builder);
runtimeManager.setJmpBuf(jmpBuf);
// TODO: Create Stop basic block on demand
m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc);

9
libevmjit/Runtime.cpp

@ -1,7 +1,5 @@
#include "Runtime.h"
#include <cstdlib>
#include <iostream>
#include <cassert>
namespace dev
@ -17,13 +15,12 @@ void Runtime::init(RuntimeData* _data, Env* _env)
m_env = _env;
}
extern "C" void ext_free(void* _data) noexcept;
Runtime::~Runtime()
{
if (m_memData)
{
std::cerr << "MEM: " << (size_t)m_memData << " [" << m_memSize << "]\n";
std::free(m_memData);
}
ext_free(m_memData); // Use helper free to check memory leaks
}
bytes_ref Runtime::getReturnData() const

3
libevmjit/RuntimeManager.cpp

@ -84,9 +84,8 @@ llvm::Twine getName(RuntimeData::Index _index)
}
}
RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, llvm::Value* _jmpBuf, code_iterator _codeBegin, code_iterator _codeEnd):
RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeBegin, code_iterator _codeEnd):
CompilerHelper(_builder),
m_jmpBuf(_jmpBuf),
m_codeBegin(_codeBegin),
m_codeEnd(_codeEnd)
{

5
libevmjit/RuntimeManager.h

@ -16,7 +16,7 @@ class Stack;
class RuntimeManager: public CompilerHelper
{
public:
RuntimeManager(llvm::IRBuilder<>& _builder, llvm::Value* _jmpBuf, code_iterator _codeBegin, code_iterator _codeEnd);
RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeBegin, code_iterator _codeEnd);
llvm::Value* getRuntimePtr();
llvm::Value* getDataPtr();
@ -43,6 +43,7 @@ public:
void abort(llvm::Value* _jmpBuf);
void setStack(Stack& _stack) { m_stack = &_stack; }
void setJmpBuf(llvm::Value* _jmpBuf) { m_jmpBuf = _jmpBuf; }
static llvm::StructType* getRuntimeType();
static llvm::StructType* getRuntimeDataType();
@ -52,7 +53,7 @@ private:
void set(RuntimeData::Index _index, llvm::Value* _value);
llvm::Function* m_longjmp = nullptr;
llvm::Value* const m_jmpBuf;
llvm::Value* m_jmpBuf = nullptr;
llvm::Value* m_dataPtr = nullptr;
llvm::Value* m_gasPtr = nullptr;
llvm::Value* m_memPtr = nullptr;

5
libevmjit/interface.cpp

@ -5,11 +5,6 @@ extern "C"
using namespace dev::eth::jit;
#ifdef _MSC_VER
#define _ALLOW_KEYWORD_MACROS
#define noexcept throw()
#endif
EXPORT void* evmjit_create() noexcept
{
// TODO: Make sure ExecutionEngine constructor does not throw

Loading…
Cancel
Save