Browse Source

Do not copy return data inside JIT

cl-refactor
Paweł Bylica 10 years ago
parent
commit
db5f405fa4
  1. 2
      evmjit/libevmjit-cpp/JitVM.cpp
  2. 1
      evmjit/libevmjit/Common.h
  3. 5
      evmjit/libevmjit/ExecutionEngine.cpp
  4. 8
      evmjit/libevmjit/ExecutionEngine.h
  5. 6
      evmjit/libevmjit/Runtime.cpp
  6. 9
      evmjit/libevmjit/Runtime.h
  7. 6
      evmjit/libevmjit/interface.cpp

2
evmjit/libevmjit-cpp/JitVM.cpp

@ -50,7 +50,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
} }
m_gas = llvm2eth(m_data.elems[RuntimeData::Gas]); m_gas = llvm2eth(m_data.elems[RuntimeData::Gas]);
return {m_engine.returnData.data(), m_engine.returnData.size()}; // TODO: This all bytesConstRef is problematic, review. return {std::get<0>(m_engine.returnData), std::get<1>(m_engine.returnData)};
} }
} }

1
evmjit/libevmjit/Common.h

@ -12,6 +12,7 @@ namespace jit
using byte = uint8_t; using byte = uint8_t;
using bytes = std::vector<byte>; using bytes = std::vector<byte>;
using bytes_ref = std::tuple<byte const*, size_t>;
using u256 = boost::multiprecision::uint256_t; using u256 = boost::multiprecision::uint256_t;
using bigint = boost::multiprecision::cpp_int; using bigint = boost::multiprecision::cpp_int;

5
evmjit/libevmjit/ExecutionEngine.cpp

@ -136,7 +136,10 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en
auto returnCode = runEntryFunc(entryFuncPtr, &runtime); auto returnCode = runEntryFunc(entryFuncPtr, &runtime);
if (returnCode == ReturnCode::Return) if (returnCode == ReturnCode::Return)
this->returnData = runtime.getReturnData(); {
returnData = runtime.getReturnData(); // Save reference to return data
std::swap(m_memory, runtime.getMemory()); // Take ownership of memory
}
auto executionEndTime = std::chrono::high_resolution_clock::now(); auto executionEndTime = std::chrono::high_resolution_clock::now();
clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms\n"; clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms\n";

8
evmjit/libevmjit/ExecutionEngine.h

@ -18,7 +18,13 @@ public:
ReturnCode run(bytes const& _code, RuntimeData* _data, Env* _env); ReturnCode run(bytes const& _code, RuntimeData* _data, Env* _env);
bytes returnData; /// Reference to returned data (RETURN opcode used)
bytes_ref returnData;
private:
/// After execution, if RETURN used, memory is moved there
/// to allow client copy the returned data
bytes m_memory;
}; };
} }

6
evmjit/libevmjit/Runtime.cpp

@ -18,7 +18,7 @@ Runtime::Runtime(RuntimeData* _data, Env* _env) :
m_currJmpBuf(m_jmpBuf) m_currJmpBuf(m_jmpBuf)
{} {}
bytes Runtime::getReturnData() const // FIXME: Reconsider returning by copy bytes_ref Runtime::getReturnData() const
{ {
// TODO: Handle large indexes // TODO: Handle large indexes
auto offset = static_cast<size_t>(llvm2eth(m_data.elems[RuntimeData::ReturnDataOffset])); auto offset = static_cast<size_t>(llvm2eth(m_data.elems[RuntimeData::ReturnDataOffset]));
@ -28,8 +28,8 @@ bytes Runtime::getReturnData() const // FIXME: Reconsider returning by copy
if (offset + size > m_memory.size()) if (offset + size > m_memory.size())
return {}; return {};
auto dataBeg = m_memory.begin() + offset; auto dataBeg = m_memory.data() + offset;
return {dataBeg, dataBeg + size}; return bytes_ref{dataBeg, size};
} }
} }

9
evmjit/libevmjit/Runtime.h

@ -2,15 +2,8 @@
#pragma once #pragma once
#include <csetjmp> #include <csetjmp>
#include <vector>
#include "Instruction.h"
#include "CompilerHelper.h"
#include "Utils.h"
#include "Type.h"
#include "RuntimeData.h" #include "RuntimeData.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#define EXPORT __declspec(dllexport) #define EXPORT __declspec(dllexport)
#else #else
@ -40,7 +33,7 @@ public:
MemoryImpl& getMemory() { return m_memory; } MemoryImpl& getMemory() { return m_memory; }
Env* getEnvPtr() { return &m_env; } Env* getEnvPtr() { return &m_env; }
bytes getReturnData() const; bytes_ref getReturnData() const;
jmp_buf_ref getJmpBuf() { return m_jmpBuf; } jmp_buf_ref getJmpBuf() { return m_jmpBuf; }
private: private:

6
evmjit/libevmjit/interface.cpp

@ -20,12 +20,12 @@ evmjit_result evmjit_run(void* _data, void* _env)
auto returnCode = engine.run(bytecode, data, static_cast<Env*>(_env)); auto returnCode = engine.run(bytecode, data, static_cast<Env*>(_env));
evmjit_result result = {static_cast<int32_t>(returnCode), 0, nullptr}; evmjit_result result = {static_cast<int32_t>(returnCode), 0, nullptr};
if (returnCode == ReturnCode::Return && !engine.returnData.empty()) if (returnCode == ReturnCode::Return && std::get<0>(engine.returnData))
{ {
// TODO: Optimized returning data. Allocating memory on client side by callback function might be a good idea // TODO: Optimized returning data. Allocating memory on client side by callback function might be a good idea
result.returnDataSize = engine.returnData.size(); result.returnDataSize = std::get<1>(engine.returnData);
result.returnData = std::malloc(result.returnDataSize); result.returnData = std::malloc(result.returnDataSize);
std::memcpy(result.returnData, engine.returnData.data(), result.returnDataSize); std::memcpy(result.returnData, std::get<0>(engine.returnData), result.returnDataSize);
} }
return result; return result;

Loading…
Cancel
Save