github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/jit/jit_driver.h (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 #pragma once 21 22 #include "common/common.h" 23 #include "core/ir_warden.h" 24 #include "fs/proto/ir.pb.h" 25 #include "jit/jit_engine.h" 26 #include "util/singleton.h" 27 28 namespace neb { 29 namespace internal { 30 class jit_driver_impl; 31 } 32 namespace core { 33 class driver; 34 } 35 class jit_driver : public ::neb::util::singleton<jit_driver> { 36 public: 37 jit_driver(); 38 ~jit_driver(); 39 40 template <typename RT, typename... ARGS> 41 RT run_ir(const std::string &name, uint64_t height, 42 const std::string &func_name, ARGS... args) { 43 auto irs_ptr = 44 core::ir_warden::instance().get_ir_by_name_height(name, height, false); 45 auto irs = *irs_ptr; 46 if (irs.size() != 1) { 47 throw std::invalid_argument("no such ir"); 48 } 49 std::string key = gen_key(irs, func_name); 50 auto ret = run_if_exists<RT>(irs.back(), func_name, args...); 51 if (ret.first) { 52 return ret.second; 53 } 54 55 irs_ptr = 56 core::ir_warden::instance().get_ir_by_name_height(name, height, true); 57 return run<RT>(key, *irs_ptr, func_name, args...); 58 } 59 60 template <typename RT, typename... ARGS> 61 std::pair<bool, RT> run_if_exists(const nbre::NBREIR &ir, 62 const std::string &func_name, 63 ARGS... args) { 64 65 std::vector<nbre::NBREIR> irs; 66 irs.push_back(ir); 67 std::string key = gen_key(irs, func_name); 68 std::unique_lock<std::mutex> _l(m_mutex); 69 auto it = m_jit_instances.find(key); 70 if (it == m_jit_instances.end()) 71 return std::make_pair(false, RT()); 72 73 auto &context = it->second; 74 context->m_time_counter = 30 * 60; 75 _l.unlock(); 76 return std::make_pair(true, context->m_jit.run<RT>(args...)); 77 } 78 79 template <typename RT, typename... ARGS> 80 RT run(const std::string &ir_key, const std::vector<nbre::NBREIR> &irs, 81 const std::string &func_name, ARGS... args) { 82 std::string key = ir_key; 83 m_mutex.lock(); 84 auto it = m_jit_instances.find(key); 85 if (it == m_jit_instances.end()) { 86 shrink_instances(); 87 m_jit_instances.insert(std::make_pair(key, make_context(irs, func_name))); 88 it = m_jit_instances.find(key); 89 } 90 auto &context = it->second; 91 context->m_time_counter = 30 * 60; 92 m_mutex.unlock(); 93 struct using_helper { 94 using_helper(jit_context *jc) : m_jc(jc) { jc->m_using = true; } 95 ~using_helper() { m_jc->m_using = false; } 96 jit_context *m_jc; 97 } _ul(context.get()); 98 context->m_using = true; 99 LOG(INFO) << "ir key " << ir_key << " irs size " << irs.size() 100 << " func_name " << func_name; 101 return context->m_jit.run<RT>(args...); 102 } 103 104 void timer_callback(); 105 106 protected: 107 void shrink_instances(); 108 109 std::string gen_key(const std::vector<nbre::NBREIR> &irs, 110 const std::string &func_name); 111 112 struct jit_context { 113 llvm::LLVMContext m_context; 114 jit::jit_engine m_jit; 115 int32_t m_time_counter; 116 bool m_using; 117 }; 118 119 std::unique_ptr<jit_driver::jit_context> 120 make_context(const std::vector<nbre::NBREIR> &irs, 121 const std::string &func_name); 122 123 bool find_mangling(llvm::Module *M, const std::string &func_name, 124 std::string &mangling_name); 125 126 protected: 127 std::mutex m_mutex; 128 std::unordered_map<std::string, std::unique_ptr<jit_context>> m_jit_instances; 129 }; // end class jit_driver; 130 } // end namespace neb