From 64e374890c5be3a6034722458cfa15087ecd526f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 28 Oct 2014 09:23:28 +0100 Subject: [PATCH] Move jmpbuf to Runtime [#81470252] --- libevmjit/ExecutionEngine.cpp | 8 ++------ libevmjit/GasMeter.cpp | 3 +-- libevmjit/Runtime.cpp | 10 +++++++++- libevmjit/Runtime.h | 8 +++++++- libevmjit/Stack.cpp | 8 +++----- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 068237af6..efa039f2b 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -35,8 +35,6 @@ ExecutionEngine::ExecutionEngine() } -extern "C" { EXPORT std::jmp_buf* rt_jmpBuf; } - int ExecutionEngine::run(std::unique_ptr _module, u256& _gas, ExtVMFace* _ext) { auto module = _module.get(); // Keep ownership of the module in _module @@ -102,21 +100,19 @@ int ExecutionEngine::run(std::unique_ptr _module, u256& _gas, ExtV _ext->code = decltype(_ext->code)(fakecode, 8); } - // Init runtime - Runtime runtime(_gas, *_ext); - auto entryFunc = module->getFunction("main"); if (!entryFunc) BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("main function not found")); ReturnCode returnCode; std::jmp_buf buf; + Runtime runtime(_gas, *_ext, buf); auto r = setjmp(buf); if (r == 0) { + auto executionStartTime = std::chrono::high_resolution_clock::now(); - rt_jmpBuf = &buf; auto result = exec->runFunction(entryFunc, {{}, llvm::GenericValue(runtime.getDataPtr())}); returnCode = static_cast(result.IntVal.getZExtValue()); diff --git a/libevmjit/GasMeter.cpp b/libevmjit/GasMeter.cpp index 317b204fc..897044cbe 100644 --- a/libevmjit/GasMeter.cpp +++ b/libevmjit/GasMeter.cpp @@ -103,10 +103,9 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager) m_builder.SetInsertPoint(outOfGasBB); //auto longjmpFunc = llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::eh_sjlj_longjmp); - auto extJmpBuf = new llvm::GlobalVariable(*module, Type::BytePtr, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "rt_jmpBuf"); llvm::Type* args[] = {Type::BytePtr, m_builder.getInt32Ty()}; auto longjmpNative = llvm::Function::Create(llvm::FunctionType::get(Type::Void, args, false), llvm::Function::ExternalLinkage, "longjmp", module); - m_builder.CreateCall2(longjmpNative, m_builder.CreateLoad(extJmpBuf), Constant::get(ReturnCode::OutOfGas)); + m_builder.CreateCall2(longjmpNative, m_runtimeManager.getJmpBuf(), Constant::get(ReturnCode::OutOfGas)); m_builder.CreateUnreachable(); m_builder.SetInsertPoint(updateBB); diff --git a/libevmjit/Runtime.cpp b/libevmjit/Runtime.cpp index 4b9464293..0be5a5b70 100644 --- a/libevmjit/Runtime.cpp +++ b/libevmjit/Runtime.cpp @@ -24,6 +24,7 @@ llvm::StructType* RuntimeData::getType() { llvm::ArrayType::get(Type::i256, _size), Type::BytePtr, + Type::BytePtr, Type::BytePtr }; type = llvm::StructType::create(elems, "RuntimeData"); @@ -58,7 +59,7 @@ llvm::Twine getName(RuntimeData::Index _index) static Runtime* g_runtime; // FIXME: Remove -Runtime::Runtime(u256 _gas, ExtVMFace& _ext): +Runtime::Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf): m_ext(_ext) { assert(!g_runtime); @@ -79,6 +80,7 @@ Runtime::Runtime(u256 _gas, ExtVMFace& _ext): set(RuntimeData::CodeSize, _ext.code.size()); // TODO: Use constant m_data.callData = _ext.data.data(); m_data.code = _ext.code.data(); + m_data.jmpBuf = _jmpBuf; } Runtime::~Runtime() @@ -167,6 +169,12 @@ llvm::Value* RuntimeManager::getCode() return getBuilder().CreateLoad(ptr, "code"); } +llvm::Value* RuntimeManager::getJmpBuf() +{ + auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 3, "jmpbufPtr"); + return getBuilder().CreateLoad(ptr, "jmpbuf"); +} + llvm::Value* RuntimeManager::getGas() { return get(RuntimeData::Gas); diff --git a/libevmjit/Runtime.h b/libevmjit/Runtime.h index ec912849a..43fafb4d9 100644 --- a/libevmjit/Runtime.h +++ b/libevmjit/Runtime.h @@ -41,12 +41,16 @@ struct RuntimeData GasLimit, CodeSize, + ReturnDataOffset = CallValue, // Reuse 2 fields for return data reference + ReturnDataSize = CallDataSize, + _size }; i256 elems[_size]; byte const* callData; byte const* code; + decltype(&jmp_buf{}[0]) jmpBuf; static llvm::StructType* getType(); }; @@ -57,7 +61,7 @@ using MemoryImpl = bytes; class Runtime { public: - Runtime(u256 _gas, ExtVMFace& _ext); + Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf); ~Runtime(); Runtime(const Runtime&) = delete; @@ -71,6 +75,7 @@ public: u256 getGas() const; bytesConstRef getReturnData() const; + decltype(&jmp_buf{}[0]) getJmpBuf() { return m_data.jmpBuf; } private: void set(RuntimeData::Index _index, u256 _value); @@ -94,6 +99,7 @@ public: llvm::Value* getGas(); // TODO: Remove llvm::Value* getCallData(); llvm::Value* getCode(); + llvm::Value* getJmpBuf(); void setGas(llvm::Value* _gas); private: diff --git a/libevmjit/Stack.cpp b/libevmjit/Stack.cpp index 6c287dc6a..144cd5d54 100644 --- a/libevmjit/Stack.cpp +++ b/libevmjit/Stack.cpp @@ -74,13 +74,11 @@ extern "C" using namespace dev::eth::jit; -extern std::jmp_buf* rt_jmpBuf; - EXPORT void stack_pop(Runtime* _rt, uint64_t _count) { auto& stack = _rt->getStack(); if (stack.size() < _count) - longjmp(*rt_jmpBuf, static_cast(ReturnCode::StackTooSmall)); + longjmp(_rt->getJmpBuf(), static_cast(ReturnCode::StackTooSmall)); stack.erase(stack.end() - _count, stack.end()); } @@ -99,7 +97,7 @@ EXPORT void stack_get(Runtime* _rt, uint64_t _index, i256* _ret) auto& stack = _rt->getStack(); // TODO: encode _index and stack size in the return code if (stack.size() <= _index) - longjmp(*rt_jmpBuf, static_cast(ReturnCode::StackTooSmall)); + longjmp(_rt->getJmpBuf(), static_cast(ReturnCode::StackTooSmall)); *_ret = *(stack.rbegin() + _index); } @@ -109,7 +107,7 @@ EXPORT void stack_set(Runtime* _rt, uint64_t _index, i256* _word) auto& stack = _rt->getStack(); // TODO: encode _index and stack size in the return code if (stack.size() <= _index) - longjmp(*rt_jmpBuf, static_cast(ReturnCode::StackTooSmall)); + longjmp(_rt->getJmpBuf(), static_cast(ReturnCode::StackTooSmall)); *(stack.rbegin() + _index) = *_word; }